Last active
January 5, 2022 07:54
-
-
Save tsaito-cyber/fc5a8a97feeae8ba2f82057fd9a14aaf to your computer and use it in GitHub Desktop.
swift-avplayer.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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