Player View is a delegated view using AVPlayer of Swift

Related tags

Video PlayerView
Overview

PlayerView

[![CI Status](http://img.shields.io/travis/David Alejandro/PlayerView.svg?style=flat)](https://travis-ci.org/David Alejandro/PlayerView) Version License Platform

An elegant wraper API for AVPlayer to get events over Delegate so you dount need to use KVO

Installation

PlayerView is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod "PlayerView"

CocoaPods

PlayerView is available through CocoaPods. To install it, simply add the following line to your Podfile:

source 'https://github.com/CocoaPods/Specs.git'
platform :iOS, '8.0'
use_frameworks!

pod 'PlayerView'

Carthage

Installation is also available using the dependency manager Carthage.

To integrate, add the following line to your Cartfile:

github "davidlondono/PlayerView" >= 0.2.7

Swift Package Manager

Installation can be done with the Swift Package Manager, add the following in your Package.swift :

import PackageDescription

let package = Package(
    name: "PlayerView",
    dependencies: [
        .Package(url: "https://github.com/davidlondono/PlayerView.git", majorVersion: 0),
    ]
)

Usage

To run the example project, clone the repo, and run pod install from the Example directory first.

Storyboard

Just add a view and add as a class on Identity inspector > Custom Class > Class, make sure to add Module if is imported externaly (Pod, Package manager ....)

import PlayerView
@IBOutlet var playerVideo: PlayerView!

Code

Just need to add de view as a normal View:

import PlayerView
let playerVideo = PlayerVideo()

//also could add frame:
// let playerVideo = PlayerVideo(frame: frame)
view.addSubView(playerVideo)

Control

//set aspect mode of video
//default AVLayerVideoGravityResizeAspectFill
playerVideo.fillMode = .ResizeAspect

//Set or Get the seconds of the current time of reproduction
//this will set to reproduce on 3.5 seconds
playerVideo.currentTime = 3.5

//define the time interval to get callback delegate of the current time of reproduction, default sends 60 times on 1 second
//default CMTimeMake(1, 60)
//this send the time one time per one second
playerVideo.interval = CMTimeMake(1, 1)

//set and get the speed of reproduction
//if speed is set to 0, the video will pause (same as playerVideo.pause())
//if speed is set to 1,0, the video will pause (same as playerVideo.play())
playerVideo.rate = 0.5

//play the video at rate 1.0
playerVideo.play()

// pause the video on current time
playerVideo.pause()


// stop the video on current time
playerVideo.stop()


// stop the video on current time
playerVideo.next()

//to set the url of Video
if let url = NSURL(string: "http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_30mb.mp4") {
	playerVideo.url = url
    //or
    playerVideo.urls = [url]

    //add videos on queue
    playerVideo.addVideosOnQueue(urls: [url])
}

//Take a screenshot on time, and return time to ensure the tolerance of the image
//on 20.7 seconds
let(image1, time1) = playerVideo.screenshotTime(20.7)
//on actual time
let(image2, time2) = playerVideo.screenshotTime()


//on actual time
let image3 = playerVideo.screenshot()

//reset queue and observers
playerVideo.resetPlayer()

Delegate

you could get event data from the PlayerView, just implement the delegate all the functions are optionals

import PlayerView
import AVFoundation
	playerVideo.delegate = self
extension MyClass:PlayerViewDelegate {


	func playerVideo(player: PlayerView, statusPlayer: PlayerViewStatus, error: NSError?) {
        //got the status of the player
		//useful to know if is ready to play
		//if status is unknown then got the error
    }

	func playerVideo(player: PlayerView, statusItemPlayer: PlayerViewItemStatus, error: NSError?) {
		//some status got here first, this is the status of AVPlayerItem
		//useful to know if is ready to play
		//if status is unknown then got the error
	}

	func playerVideo(player: PlayerView, loadedTimeRanges: [PlayerviewTimeRange]) {
		//got the buffer of the video
		//to know the progress loaded

		//this will get the seconds of the end of the buffer
		//loadedTimeRanges.first!.end.seconds

	}

	func playerVideo(player: PlayerView, duration: Double) {
		//the player knows the duration of the video to reproduce on seconds
	}

	func playerVideo(player: PlayerView, currentTime: Double) {
		//executed using the playerVideo.interval
        //only executed when the is reproducing, on pause (rate == 1) this doesn't execute
		//default executed like 60 frames per seconds, so 60 times on a second
	}

	func playerVideo(player: PlayerView, rate: Float) {
		//if the speed of reproduction changed by pausing, playing or changing speed
	}

    func playerVideo(playerFinished player: PlayerView) {
        //when the video finishes the reproduction to the end
    }
}

Extra Info

  • If you like another shorcut, have a better implementation of something or just say thanks, just send me an email [[email protected]](mailto:[email protected]?subject=PlayerView is Awesome)

  • Im using a video on http, so I needed to add this on the info.plist to accept all on http, this is not safe to use on production, so better to add only trusted domains or use https

<key>NSAppTransportSecurity</key>
<dict>
    <!--Include to allow all connections (DANGER)-->
    <key>NSAllowsArbitraryLoads</key>
<true/>
</dict>

Author

David Alejandro, [[email protected]](mailto:[email protected]?subject=PlayerView is Awesome)

License

PlayerView is available under the MIT license. See the LICENSE file for more info.

Comments
  • ScreenShot Func Question

    ScreenShot Func Question

    I take a screenshot from my video. If the video is Portrait,after screenshot, my image show Landscape, If the video is Landscape , and the image is the same with Video.

    Could you please teach me how to fix it?

    Wring Direction Pic Correct Direction Pic

    PS. I use the function to fix my img from screenshot. But it does not work. Thank you!

    extension UIImage {
    
      func fixOrientation() -> UIImage {
        if (self.imageOrientation == .Up) {
          return self
        }
    
        var transform = CGAffineTransformIdentity
    
        switch (self.imageOrientation) {
        case .Down, .DownMirrored:
          transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height)
          transform = CGAffineTransformRotate(transform, CGFloat(M_PI))
    
        case .Left, .LeftMirrored:
          transform = CGAffineTransformTranslate(transform, self.size.width, 0)
          transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2))
    
        case .Right, .RightMirrored:
          transform = CGAffineTransformTranslate(transform, 0, self.size.height)
          transform = CGAffineTransformRotate(transform, CGFloat(-M_PI_2))
    
        default:
          break
        }
    
        switch (self.imageOrientation) {
        case .UpMirrored, .DownMirrored:
          transform = CGAffineTransformTranslate(transform, self.size.width, 0)
          transform = CGAffineTransformScale(transform, -1, 1)
    
        case .LeftMirrored, .RightMirrored:
          transform = CGAffineTransformTranslate(transform, self.size.height, 0)
          transform = CGAffineTransformScale(transform, -1, 1)
    
        default:
          break
        }
    
        let ctx = CGBitmapContextCreate(nil, Int(self.size.width), Int(self.size.height),
          CGImageGetBitsPerComponent(self.CGImage), 0,
          CGImageGetColorSpace(self.CGImage),
          CGImageGetBitmapInfo(self.CGImage).rawValue)
        CGContextConcatCTM(ctx, transform)
    
        switch (self.imageOrientation) {
        case .Left, .LeftMirrored, .Right, .RightMirrored:
          CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage)
    
        default:
          CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.CGImage)
        }
    
        // And now we just create a new UIImage from the drawing context
        let cgimg = CGBitmapContextCreateImage(ctx)
        return UIImage(CGImage: cgimg!)
      }
    }
    

    let fixedImage = image.fixOrientation()

    bug 
    opened by SuYungCheng 5
  • After using PlayerView Podfile, there appear downcast problem

    After using PlayerView Podfile, there appear downcast problem

    Before I installed PlayerView, I have only one Podfile "AWSS3" ,Podfile looks like that:

    • source 'https://github.com/CocoaPods/Specs.git'
    • platform :ios, '8.0'
    • pod 'AWSS3'

    And it has "no error",

    After install PlaerView , Podfile looks like that:

    • source 'https://github.com/CocoaPods/Specs.git'
    • platform :ios, '8.0'
    • pod 'AWSS3'
    • use_frameworks!
    • pod 'PlayerView'

    Here comes many Downcast problems. And remove PlayerView, It comes normally again. How can I build succeed with PlayerView?

    opened by SuYungCheng 4
  • Carthage PlayerView Problem

    Carthage PlayerView Problem

    I use Carthage to download PlayerView,and install well.

    But there seems have some thing wrong in "setUrl" method.

    
    import UIKit
    import PlayerView
    import AVFoundation
    
    
    class ViewController: UIViewController {
    
        var currentTimes:String?
    
        @IBOutlet var slider: UISlider!
    
        @IBOutlet var rateLabel: UILabel!
    
        @IBOutlet var progressBar: UIProgressView!
    
        @IBOutlet var playerVideo: PlayerView!
    
    
        @IBOutlet var playButton: UIButton!
    
    
        @IBAction func sliderChange(sender: UISlider) {
    
            playerVideo.currentTime = Double(sender.value)
        }
    
    
        @IBAction func sliderBegin(sender: AnyObject) {
            print("beginEdit")
            isEditingSlider = true
    
        }
    
        @IBAction func sliderEnd(sender: AnyObject) {
            print("endEdit")
            isEditingSlider = false
        }
    
    
        @IBAction func backwardTouch(sender: AnyObject) {
    
            playerVideo.rate = playerVideo.rate - 0.5
    
        }
    
        @IBAction func playTouch(sender: AnyObject) {
            if playerVideo.rate == 0 {
                playerVideo.play()
            } else {
                playerVideo.pause()
            }
        }
    
        @IBAction func fowardTouch(sender: AnyObject) {
            playerVideo.rate = playerVideo.rate + 0.5
    
        }
    
        func changeFill(sender: AnyObject) {
            switch playerVideo.fillMode {
            case .Some(.ResizeAspect):
                playerVideo.fillMode = .ResizeAspectFill
            case .Some(.ResizeAspectFill):
                playerVideo.fillMode = .Resize
            case .Some(.Resize):
                playerVideo.fillMode = .ResizeAspect
            default:
                break
            }
        }
    
        var duration: Float!
        var isEditingSlider = false
        let tap = UITapGestureRecognizer()
    
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a nib.
            playerVideo.delegate = self
            let url = NSURL(string: "http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_30mb.mp4")!
    
    
           **#  // it say playerView has no member setUrl**
            playerVideo.setUrl(url)
    
    
            tap.numberOfTapsRequired = 2
            tap.addTarget(self, action: "changeFill:")
            view.addGestureRecognizer(tap)
    
        }
    
        override func loadView() {
            super.loadView()
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    
    
    }
    extension ViewController: PlayerViewDelegate {
    
        func playerVideo(player: PlayerView, statusPlayer: PlayerViewStatus, error: NSError?) {
            print(statusPlayer)
        }
    
        func playerVideo(player: PlayerView, statusItemPlayer: PlayerViewItemStatus, error: NSError?) {
    
        }
        func playerVideo(player: PlayerView, loadedTimeRanges: [PlayerviewTimeRange]) {
    
            let dur2 = Float(loadedTimeRanges.first!.end.seconds)
            let progress = dur2 / duration
            progressBar?.progress = progress
    
            if loadedTimeRanges.count > 1 {
                print(loadedTimeRanges.count)
            }
            //print("progress",progress)
        }
        func playerVideo(player: PlayerView, duration: Double) {
            //print(duration.seconds)
            self.duration = Float(duration)
            slider?.maximumValue = Float(duration)
        }
    
        func playerVideo(player: PlayerView, currentTime: Double) {
            if !isEditingSlider {
                slider.value = Float(currentTime)
            }
            print("curentTime",currentTime)
            self.currentTimes = String(currentTime)
        }
    
        func playerVideo(player: PlayerView, rate: Float) {
            rateLabel.text = "x\(rate)"
    
    
            let buttonImageName = rate == 0.0 ? "PlayButton" : "PauseButton"
    
            let buttonImage = UIImage(named: buttonImageName)
    
            playButton.setImage(buttonImage, forState: .Normal)
    
            //        slider.value = Float(currentTime)
            //        print(currentTime.seconds)
        }
    }
    
    help wanted 
    opened by SuYungCheng 2
  • Refactor + features + bug fix

    Refactor + features + bug fix

    Refactore source code Fix infinite delegate call for currentTime notification New optional for delegate methods (not necessary implements all delegate methods) Notification of finish PS: Broken changes: setUrl(..) changed to url = ...

    opened by alexnaldo 2
  • sometimes, currentTime delegate is not called

    sometimes, currentTime delegate is not called

    Hello, the delegate

    playerVideo(player: PlayerView, currentTime: Double)
    

    sometimes not called unless i explicitly I pause and play the video, which causes the time label to not be updated.

    I hope it can be fixed.

    opened by bluemix 1
  • Crash in setter of currentTime property: *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[AVPlayerItem seekToTime:toleranceBefore:toleranceAfter:completionHandler:] Seeking is not possible to time {INVALID}'

    Crash in setter of currentTime property: *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[AVPlayerItem seekToTime:toleranceBefore:toleranceAfter:completionHandler:] Seeking is not possible to time {INVALID}'

    Hi there,

    firstly thanks for the library, it works really well. I got one issue though with a crash pretty frequently happening in the setter of the currentTime property in line 143: player!.seekToTime(newTime,toleranceBefore: CMTime.zero,toleranceAfter: CMTime.zero)

    It crashes due to the reason of newTime being invalid. I added a workaround which works fine for me. I just do a safety check on newTime before calling seekToTime on the player: if !CMTIME_IS_INVALID(newTime) { player!.seekToTime(newTime,toleranceBefore: CMTime.zero,toleranceAfter: CMTime.zero) }`

    Could you add the code to the library or do you see problems with it? Or would you like me to create a pull request for it?

    Thanks in advance

    opened by bughana 1
  • Need for isPlaying property to check is video is playing or not.

    Need for isPlaying property to check is video is playing or not.

    Hello, I think the PlayerView control should include a property like isPlaying using which one can check if the video is being played and it is not explicitly paused or stopped. Using rate property works with small remote videos (and local videos). But rate changes to 0 during buffering which is problematic to use because I am using rate 1 as playing and rate 0 as paused/stopped.

    opened by gauravlnx 1
  • Not receiving callback from: func playerVideo(player: PlayerView, currentTime: Double)

    Not receiving callback from: func playerVideo(player: PlayerView, currentTime: Double)

    Hey, loving the video player view so far however I seem to have an issue getting callback from func playerVideo(player: PlayerView, currentTime: Double). I have the delegate set and func playerVideo(player: PlayerView, duration: Double) works fine for getting the duration. Tried setting a different interval too using videoPlayerView.interval = CMTimeMake(1, 1). Any ideas what I might be doing wrong here?

    opened by kekearif 3
Releases(0.2.6)
  • 0.2.6(May 23, 2016)

    useful on Cells, so it can reset the player observers with:

    playerView.resetPlayer()
    

    changed all the typealias for player but make sure to import Video Library

    import AVFoundation.AVPlayer
    
    Source code(tar.gz)
    Source code(zip)
  • 0.2.5(May 18, 2016)

    Now The Player can have a list of URLs to reproduce

    added method for initialize Queue

        playerView.urls = [urls]
    

    add more videos for queue

        playerView.addVideosOnQueue(urls: [urls])
        playerView.addVideosOnQueue(url1,url2...)
    

    play next video

        playerView.next()
    
    Source code(tar.gz)
    Source code(zip)
  • 0.1.5(Mar 31, 2016)

    change the:

    playerView.setUrl(url)
    

    to

    playerView.url = url
    

    added the delegate function:

    func playerVideo(playerFinished player: PlayerView)
    

    all the functions for the delegate are now optional

    Source code(tar.gz)
    Source code(zip)
Owner
null
Swifty360Player - iOS 360-degree video player streaming from an AVPlayer.

Swifty360Player iOS 360-degree video player streaming from an AVPlayer. Demo Requirements Swifty360Player Version Minimum iOS Target Swift Version 0.2

Abdullah Selek 148 Dec 18, 2022
Pretty iOS mobile screens + AVPlayer video view ––– made in SwiftUI

UrbanVillageProjectScreens Recreated UI screens from the conceptual Urban Village Project. Read more about the project here. Please open an issue if y

10011.co 23 Dec 29, 2022
Musical Player - A Simple Musical Player For iOS

Musical_Player The app is a musical player. It was written as an task for a mobi

null 1 Nov 26, 2022
Gumlet analytics integration with AVPlayer for iOS native applications.

gumlet-Insights-avplayer Gumlet Insights integration with AVPlayer for iOS native applications. This Insights enables you to get useful data about vid

Gumlet 0 Dec 15, 2021
VIMVideoPlayer is a simple wrapper around the AVPlayer and AVPlayerLayer classes.

VIMVideoPlayer is a simple wrapper around the AVPlayer and AVPlayerLayer classes.

Vimeo 280 May 11, 2022
NYT360Video plays 360-degree video streamed from an AVPlayer on iOS.

NYT360Video 360º video playback from The New York Times NYT360Video plays spherical 360º video, allowing the user to explore the video via pan gesture

The New York Times 270 Nov 23, 2022
SuperPlayer is a library to wrap AVPlayer with Composable Architecture.

SuperPlayer is a library to wrap AVPlayer with Composable Architecture. It can be used in SwiftUI and UIKit.

Tokopedia 13 Dec 21, 2022
NYT360Video plays 360-degree video streamed from an AVPlayer on iOS.

NYT360Video 360º video playback from The New York Times NYT360Video plays spherical 360º video, allowing the user to explore the video via pan gesture

The New York Times 270 Nov 23, 2022
Overlay alpha channel video animation player view using Metal.

Overlay alpha channel video animation player view using Metal. Example To run the example project, clone the repo, and run pod install from the Exampl

noppefoxwolf 244 Jan 1, 2023
A reactive audio player for iOS using RxSwift

ESAudioPlayer: A reactive audio player for iOS ESAudioPlayer is a reactive audio player for iOS using RxSwift. It provides basic audio management feat

Extreme Solution 4 Jun 22, 2022
MMPlayerView - Custom AVPlayerLayer on view and transition player with good effect like youtube and facebook

MMPlayerView Demo-Swift List / Shrink / Transition / Landscape MMPlayerLayer ex. use when change player view frequently like tableView / collectionVie

Millman Yang 724 Nov 24, 2022
📽 A video player for SwiftUI, support for caching, preload and custom control view.

Features QuickStart Advances Installation Requirements License Demo Clone or download the project. In the terminal, run swift package resolve. Open Vi

Gesen 437 Jan 5, 2023
▶️ video player in Swift, simple way to play and stream media on iOS/tvOS

Player Player is a simple iOS video player library written in Swift. Looking for an obj-c video player? Check out PBJVideoPlayer (obj-c). Looking for

patrick piemonte 2k Jan 2, 2023
FWVideoPlayer is video Player for iOS in Swift.

FWVideoPlayer Desc FWVideoPlayer is video Player for iOS in Swift. It can play video and audio. You can use it easy. Example To run the example projec

null 1 Oct 15, 2021
360 video player for iOS written in swift - a subset of SceneKit that works

DDDKit An open source library to support 360 videos and pictures. It's designed as a generic 3D library that you can use for much more! Example of use

Guillaume Sabran 123 Aug 9, 2022
Audio player demo based on Swift and SwiftUI, which can play local or network audio.

SwiftAudioDemo Audio player demo based on Swift and SwiftUI, which can play local or network audio. In this demo, I have made a radio player to play n

Jensen Zhang 6 Mar 13, 2022
YHPlayer - An easy-to-use video player based on swift language

YHPlayer An easy-to-use video player based on swift language Features Plays loca

null 9 Dec 1, 2022
MobilePlayer - A powerful and completely customizable media player for iOS

MobilePlayer A powerful and completely customizable media player for iOS. Table of Contents Features Installation Usage Customization Skinning Showing

Sahin Boydas 3k Jan 2, 2023
VGPlayer - 📺 A simple iOS video player by Vein.

Swift developed based on AVPlayer iOS player,support horizontal gestures Fast forward, pause, vertical gestures Support brightness and volume adjustment, support full screen, adaptive screen rotation direction.

Wen Rong 399 Dec 23, 2022