Swift Media Player
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

393 lines
14 KiB

//
// Created by Marco Schmickler on 26.05.15.
// Copyright (c) 2015 Marco Schmickler. All rights reserved.
//
import Foundation
import UIKit
import MediaPlayer
import ALMoviePlayerController
import Haneke
class VideoPlayerController: UIViewController, ItemController {
var moviePlayer: ALMoviePlayerController?
var currentItem: MediaItem?
var completionHandler: ((Void) -> Void)?
var buttons = Dictionary<UIButton, MediaItem>()
var barbutton: UIBarButtonItem?
var speedButton: UIBarButtonItem?
var playButton: UIBarButtonItem?
var backButton: UIBarButtonItem?
var reviewButton: UIBarButtonItem?
let speedOptions = [ 0.25, 0.5, 0.75, 1.0, 2.0 ]
var speedOption = 3
var thumbnailTime: TimeInterval = 0.0
var edit = true
var allowEdit = true
var index = 0
func setCompletionHandler(handler: @escaping ((Void) -> Void)) {
completionHandler = handler
}
override func viewDidLoad() {
super.viewDidLoad()
barbutton = UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(VideoPlayerController.twoFingersTwoTaps));
navigationItem.rightBarButtonItems = [barbutton!]
backButton = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(VideoPlayerController.back(_:)))
speedButton = UIBarButtonItem(title:"1.0", style:UIBarButtonItemStyle.plain, target: self, action: #selector(VideoPlayerController.speed(_:)))
playButton = UIBarButtonItem(barButtonSystemItem: .play, target: self, action: #selector(VideoPlayerController.startstop(_:)))
reviewButton = UIBarButtonItem(title:"Edit ", style:UIBarButtonItemStyle.plain, target: self, action: #selector(VideoPlayerController.doEdit(_:)))
navigationItem.leftBarButtonItems = [backButton!, playButton!, speedButton!, reviewButton!]
if let c = currentItem, let url = c.playerURL {
print(url)
play(url as URL)
}
}
func setCurrentItem(item: MediaItem) {
currentItem = item
}
func doEdit(_ sender: AnyObject) {
if (!allowEdit) {
return
}
if (edit) {
edit = false
reviewButton!.tintColor = UIColor.blue
}
else {
edit = true
reviewButton!.tintColor = UIColor.yellow
}
}
func startstop(_ sender: AnyObject) {
if moviePlayer!.playbackState == MPMoviePlaybackState.playing {
moviePlayer!.pause()
}
else {
moviePlayer!.play()
Timer.scheduledTimer(timeInterval: 0.5,
target: self,
selector: #selector(resumePlay),
userInfo: nil,
repeats: false)
}
print("play")
}
func speed(_ sender: AnyObject) {
speedOption += 1
if speedOption >= speedOptions.count {
speedOption = 0
}
moviePlayer!.currentPlaybackRate = Float(speedOptions[speedOption])
speedButton!.title = "\(moviePlayer!.currentPlaybackRate)"
print("speed \(moviePlayer!.currentPlaybackRate)")
}
@IBAction func back(_ sender: AnyObject) {
completionHandler!()
}
func play(_ url: URL) {
self.moviePlayer = ALMoviePlayerController(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height))
if let player = self.moviePlayer {
let movieControls = ALMoviePlayerControls(moviePlayer: player, style: ALMoviePlayerControlsStyleDefault)!;
movieControls.fadeDelay = 60
player.controls = movieControls
movieControls.style = ALMoviePlayerControlsStyleEmbedded
NotificationCenter.default.addObserver(self, selector: #selector(VideoPlayerController.exitedFullscreen), name: NSNotification.Name.MPMoviePlayerDidExitFullscreen, object: nil);
NotificationCenter.default.addObserver(self, selector: #selector(VideoPlayerController.enteredFullscreen), name: NSNotification.Name.MPMoviePlayerDidEnterFullscreen, object: nil);
NotificationCenter.default.addObserver(self, selector: #selector(VideoPlayerController.showThumbnail(_:)), name: NSNotification.Name.MPMoviePlayerThumbnailImageRequestDidFinish, object: nil);
NotificationCenter.default.addObserver(self, selector: #selector(VideoPlayerController.playerItemDidReachEnd(_:)), name: NSNotification.Name.MPMoviePlayerLoadStateDidChange, object: nil);
player.view.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height)
player.view.sizeToFit()
player.scalingMode = MPMovieScalingMode.aspectFit
// player.controlStyle = MPMovieControlStyle.Embedded
player.movieSourceType = MPMovieSourceType.streaming
player.repeatMode = MPMovieRepeatMode.one
player.contentURL = url
self.view.addSubview(player.view)
installGestures(player.view)
update()
}
}
func playerItemDidReachEnd(_ note: Notification) {
print("finish")
// Timer.scheduledTimer(timeInterval: 0.6, target: self, selector: #selector(update), userInfo: nil, repeats: false)
}
func showThumbnail(_ note: Notification) {
let userInfo = note.userInfo! as NSDictionary
let thumbnail = userInfo.object(forKey: MPMoviePlayerThumbnailImageKey) as! UIImage
let time = userInfo.object(forKey: MPMoviePlayerThumbnailTimeKey) as! TimeInterval
let newItem = MediaItem(name: currentItem!.name, path: currentItem!.path, root: currentItem!.root, type: ItemType.SNAPSHOT)
newItem.image = thumbnail
newItem.time = time
newItem.parent = currentItem!
currentItem!.children.append(newItem)
print(newItem.time)
addItemButton(newItem)
}
func addItemButton(_ newItem: MediaItem) {
let frame = CGRect(x: 0, y: 0, width: 66.0, height: 44.0);
let button = UIButton(frame: frame)
button.showsTouchWhenHighlighted = true
button.addTarget(self, action: #selector(thumbnailClicked(_:)), for: .touchDown)
if newItem.image != nil {
let icon = newItem.image!.scaleToSize(66.0, height: 44.0)
button.setBackgroundImage(icon, for: UIControlState());
} else {
if newItem.thumbUrl != nil {
let URL = Foundation.URL(string: newItem.thumbUrlAbsolute)!
Shared.imageCache.fetch(URL: URL).onSuccess {
i in
let icon = i.scaleToSize(66.0, height: 44.0)
button.setBackgroundImage(icon, for: UIControlState.normal);
}
}
}
let barbutton = UIBarButtonItem(customView: button);
if navigationItem.rightBarButtonItems == nil {
navigationItem.rightBarButtonItems = []
}
navigationItem.rightBarButtonItems!.append(barbutton)
buttons[button] = newItem
}
func thumbnailClicked(_ source: UIButton) {
moviePlayer!.currentPlaybackTime = buttons[source]!.time!
moviePlayer!.currentPlaybackRate = Float(speedOptions[speedOption])
print("goto \(buttons[source]!.time!) is \(moviePlayer!.currentPlaybackTime)")
}
func update() {
if let player = self.moviePlayer {
// if !(player.duration > 0.0) {
// print("again")
// Timer.scheduledTimer(timeInterval: 0.3, target: self, selector: #selector(update), userInfo: nil, repeats: false)
// return
// }
reviewButton!.title = currentItem!.name
if currentItem!.type == ItemType.SNAPSHOT {
player.currentPlaybackTime = currentItem!.time!
currentItem = currentItem!.parent
} else {
if !currentItem!.children.isEmpty {
player.currentPlaybackTime = currentItem!.children[0].time!
}
else {
print(player.duration)
player.currentPlaybackTime = player.duration / 2
}
}
navigationItem.rightBarButtonItems = [barbutton!]
for c in currentItem!.children {
addItemButton(c)
}
player.play()
}
}
func enteredFullscreen() {
let mp = UIApplication.shared.keyWindow;
if let moviePlayerContainer = mp!.recursiveSearchForViewWithName("MPVideoContainerView") {
if (moviePlayerContainer.gestureRecognizers != nil) {
return;
}
installGestures(moviePlayerContainer)
}
}
func exitedFullscreen() {
moviePlayer!.view.removeFromSuperview();
moviePlayer = nil;
NotificationCenter.default.removeObserver(self);
}
func installGestures(_ moviePlayer: UIView) {
let twoFingersTwoTapsGesture = UITapGestureRecognizer(target: self, action: #selector(twoFingersTwoTaps))
twoFingersTwoTapsGesture.numberOfTapsRequired = 2
twoFingersTwoTapsGesture.numberOfTouchesRequired = 2
moviePlayer.addGestureRecognizer(twoFingersTwoTapsGesture)
let sR = UISwipeGestureRecognizer(target: self, action: #selector(swipeRight))
sR.direction = UISwipeGestureRecognizerDirection.right
sR.numberOfTouchesRequired = 1
moviePlayer.addGestureRecognizer(sR)
let sL = UISwipeGestureRecognizer(target: self, action: #selector(swipeLeft))
sL.direction = UISwipeGestureRecognizerDirection.left
sL.numberOfTouchesRequired = 1
moviePlayer.addGestureRecognizer(sL)
let sR2 = UISwipeGestureRecognizer(target: self, action: #selector(swipeDown))
sR2.direction = UISwipeGestureRecognizerDirection.down
sR2.numberOfTouchesRequired = 1
moviePlayer.addGestureRecognizer(sR2)
let sR3 = UISwipeGestureRecognizer(target: self, action: #selector(swipeUp))
sR3.direction = UISwipeGestureRecognizerDirection.up
sR3.numberOfTouchesRequired = 1
moviePlayer.addGestureRecognizer(sR3)
}
func swipeUp() {
print("u")
if let player = self.moviePlayer {
print("Type: \(currentItem!.type) Count: \(currentItem!.children.count) Index: \(index) Current: \(currentItem!.index)")
if !edit && (currentItem!.children.isEmpty || !(index < currentItem!.children.count - 1)) {
print ("switch")
var newIndex = currentItem!.index + 1
if currentItem!.parent!.children.count <= newIndex {
newIndex = 0
}
currentItem = currentItem!.parent!.children[newIndex]
print("'Switched Type: \(currentItem!.type) Count: \(currentItem!.children.count) Index: \(index) Current: \(currentItem!.index)")
index = 0
player.contentURL = currentItem!.playerURL
player.play()
Timer.scheduledTimer(timeInterval: 1.2, target: self, selector: #selector(update), userInfo: nil, repeats: false)
return
}
if !(currentItem!.children.isEmpty) {
print ("switch internal")
if index < currentItem!.children.count - 1 {
index+=1;
} else {
index = 0;
}
let child = currentItem!.children[index]
player.currentPlaybackTime = child.time!
moviePlayer!.currentPlaybackRate = Float(speedOptions[speedOption])
}
}
}
func swipeRight() {
print("r")
if let player = self.moviePlayer {
moviePlayer!.currentPlaybackRate = Float(0.0)
player.currentPlaybackTime = player.currentPlaybackTime - 30.0
Timer.scheduledTimer(timeInterval: 0.9,
target: self,
selector: #selector(resumePlay),
userInfo: nil,
repeats: false)
}
}
func swipeDown() {
print("d")
if let player = self.moviePlayer {
if !edit {
var newIndex = currentItem!.index - 1
if newIndex < 0 {
newIndex = 0
}
currentItem = currentItem!.parent!.children[newIndex]
index = 0;
player.contentURL = currentItem!.playerURL
player.play()
Timer.scheduledTimer(timeInterval: 1.2, target: self, selector: #selector(update), userInfo: nil, repeats: false)
return
}
player.currentPlaybackTime = player.currentPlaybackTime + 10.0
Timer.scheduledTimer(timeInterval: 0.9,
target: self,
selector: #selector(resumePlay),
userInfo: nil,
repeats: false)
}
}
func swipeLeft() {
print("l")
if let player = self.moviePlayer {
moviePlayer!.currentPlaybackRate = Float(0.0)
player.currentPlaybackTime = player.currentPlaybackTime + 30.0
Timer.scheduledTimer(timeInterval: 0.9,
target: self,
selector: #selector(resumePlay),
userInfo: nil,
repeats: false)
}
}
@objc func resumePlay() {
moviePlayer!.currentPlaybackRate = Float(speedOptions[speedOption])
print("resumePlay")
}
func twoFingersTwoTaps() {
if edit {
thumbnailTime = moviePlayer!.currentPlaybackTime
print("tap \(thumbnailTime)")
moviePlayer!.requestThumbnailImages(atTimes: [thumbnailTime],
timeOption: MPMovieTimeOption.exact);
}
else {
NetworkManager.sharedInstance.favItem(currentItem!)
}
}
}