Skip to content

Instantly share code, notes, and snippets.

@takuma-saito
Last active January 5, 2022 07:54
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save takuma-saito/fc5a8a97feeae8ba2f82057fd9a14aaf to your computer and use it in GitHub Desktop.
Save takuma-saito/fc5a8a97feeae8ba2f82057fd9a14aaf to your computer and use it in GitHub Desktop.
swift-avplayer.swift
import AVFoundation
import AVKit
import UIKit
extension CMTime {
var asDouble: Double {
get {
return Double(self.value) / Double(self.timescale)
}
}
var asFloat: Float {
get {
return Float(self.value) / Float(self.timescale)
}
}
}
extension CMTime: CustomStringConvertible {
public var description: String {
get {
let seconds = Int(round(self.asDouble))
return String(format: "%02d:%02d", seconds / 60, seconds % 60)
}
}
}
class PlayerView: UIView {
var player: AVPlayer? {
get {
return playerLayer.player
}
set {
playerLayer.player = newValue
}
}
var playerLayer: AVPlayerLayer {
return layer as! AVPlayerLayer
}
override static var layerClass: AnyClass {
return AVPlayerLayer.self
}
}
class ViewController: UIViewController {
var playButton: UIButton!
var playerView: PlayerView!
var playerTimeLabel: UILabel!
var seekSlider: UISlider!
var isActive: Bool = false
var videoURL: URL!
var duration: CMTime {
return self.playerView.player!.currentItem!.asset.duration
}
convenience init(url: String) {
self.init()
self.videoURL = URL(string: url)!
}
override func viewDidLoad() {
self.view.backgroundColor = UIColor.white
self.playButton = setPlayButton()
self.playerView = setPlayerView()
self.playerTimeLabel = setTextLabel(cmtime: kCMTimeZero)
print(self.duration)
self.seekSlider = setSeekSlider()
playerView.player?.addPeriodicTimeObserver(
forInterval: CMTime(seconds: 1, preferredTimescale: 100),
queue: DispatchQueue.main,
using: { [weak self] (cmtime) in
print(cmtime)
self?.playerTimeLabel.text = cmtime.description
})
self.view.addSubview(playerView)
self.view.addSubview(seekSlider)
self.view.addSubview(playerTimeLabel)
self.view.addSubview(playButton)
}
private func setTextLabel(cmtime: CMTime) -> UILabel {
let label = UILabel()
label.text = cmtime.description
label.frame = CGRect(x: 0, y: 350, width: 100, height: 50)
return label
}
private func setSeekSlider() -> UISlider {
let slider = UISlider()
slider.frame = CGRect(x: 0, y: 400, width: 320, height: 50)
slider.addTarget(
self,
action: #selector(self.changeSeekSlider(_:)),
for: .valueChanged)
return slider
}
func changeSeekSlider(_ sender: UISlider) {
let seekTime = CMTime(seconds: Double(sender.value) * self.duration.asDouble, preferredTimescale: 100)
self.seekToTime(seekTime)
}
private func seekToTime(_ seekTime: CMTime) {
print(seekTime)
self.playerView.player?.seek(to: seekTime)
self.playerTimeLabel.text = seekTime.description
}
private func setPlayerView() -> PlayerView {
let player = AVPlayer(url: self.videoURL)
let playerView = PlayerView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))
playerView.player = player
return playerView
}
private func setPlayButton() -> UIButton {
let playButton = UIButton()
playButton.frame = CGRect(x: 0, y: 300, width: 100, height: 30)
playButton.backgroundColor = UIColor.blue
playButton.layer.masksToBounds = true
playButton.setTitle("PLAY", for: .normal)
playButton.layer.cornerRadius = 8.0
playButton.addTarget(
self,
action: #selector(self.clickPlayButton(_:)),
for: .touchUpInside)
return playButton
}
func clickPlayButton(_ sender: UIButton) {
playButton.setTitle(isActive ? "PLAY" : "STOP", for: .normal)
isActive ? playerView.player?.pause() : playerView.player?.play()
self.isActive = !self.isActive
print("clicked -> \(isActive)")
}
}
let liveView = ViewController(url: "https://mnmedias.api.telequebec.tv/m3u8/29880.m3u8")
import PlaygroundSupport
PlaygroundPage.current.liveView = liveView
PlaygroundPage.current.needsIndefiniteExecution = true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment