piemonte / player Goto Github PK
View Code? Open in Web Editor NEW▶️ Play and stream media in Swift
License: MIT License
▶️ Play and stream media in Swift
License: MIT License
Roberts-MacBook-Pro:VideoPlayer hcri50$ pod install
Updating local specs repositories
Analyzing dependencies
Pre-downloading: Player
from https://github.com/CocoaPods/Specs.git
[!] Unable to find a specification for 'Player'.
[!] Unable to load a podspec from YSMAutoScrollView.podspec
, skipping:
Is a directory - /var/folders/_5/d3gn9brd5sbc92c2fl1npk800000gn/T/d20151123-5497-1c6l29j/Specs/YSMAutoScrollView.podspec
Roberts-MacBook-Pro:VideoPlayer hcri50$
Hi. I got the example working and now I want to hook it up to play local video files I have in my Documents directory.
Specifically, I have a path like:
let ViewControllerVideoPath = "/var/mobile/Containers/Data/Application/5E9673F2-5258-4386-BF17-FAC06E6059AF/Documents/test.mp4"
However, when I get it that path it does not play.
I notice it fails in:
for key in keys {
var error: NSError?
let status = self.asset.statusOfValueForKey(key, error:&error)
if status == .Failed {
print("failed")
self.playbackState = .Failed
self.delegate.playerPlaybackStateDidChange(self)
return
}
}
Am I doing something wrong?
Thanks.
Would it be possible to support tvOS? Cheers!
I have tried to change the condition of muted property to self.player.muted=true but it returns a nil value.Is there any other way to mute the audio
When the player appears, Spotify and music app music stop playing. I made a Issue earlier, but got closed, and the fix did not work.. Take a look at my code here:
self.player = Player()
self.player.delegate = self
player.view.frame.size.width = UIScreen.mainScreen().bounds.size.width
player.view.frame.size.height = player.view.frame.size.width
player.fillMode = AVLayerVideoGravityResizeAspectFill
player.view.sizeToFit()
videoCell!.addSubview(player.view)
// audio session
let audioSession = AVAudioSession.sharedInstance()
try! audioSession.setCategory(AVAudioSessionCategoryAmbient, withOptions: AVAudioSessionCategoryOptions.MixWithOthers)
let videoUrl: NSURL = fileUrl!
self.player.setUrl(videoUrl)
self.player.playFromBeginning()
self.player.playbackLoops = true
let tapGestureRecognizer: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "handleTapGestureRecognizer:")
tapGestureRecognizer.numberOfTapsRequired = 1
self.player.view.addGestureRecognizer(tapGestureRecognizer)
Hi again @piemonte,
What would be the best way for caching AVAssets for multiple Player instances, i.e. a tableview and in each cell holds a Player instance with a different URL path? I am striving for the same logic being done for images, like in many other image caching optimised examples and libraries specialised with images. I will probably use HanekeSwift or something that I have to build from the ground up. Probably I have to modify or customize the setupAsset function in Player, but I am not certain yet.
I am just curious what comes to your mind about this @piemonte?
The delegate methods are optional?
I am trying to use Player, and I have my back-end API with Lumen (Laravel). I have a video that I found on Vine, that I am going to use in the examples below.
First, when I use your direct Vine url,
let videoUrl = NSURL(string: "https://v.cdn.vine.co/r/videos/AA3C120C521177175800441692160_38f2cbd1ffb.1.5.13763579289575020226.mp4")!
and call self.player.setUrl(videoUrl)
in ViewDidLoad, it works.
Secondly, I downloaded the video file from the Vine link, called it vine.mp4. I dragged it into xCode project directory (+ copy) and included it in 'Copy Bundle Resources'. Then I used:
let path = NSBundle.mainBundle().pathForResource("vine", ofType:"mp4")!
let videoUrl = NSURL(fileURLWithPath: path)
It works again!
Problem: Lastly, I tried to add the video to my server and create a route, so I can watch the video directly by using http://myapi.dev/videos/vine.mp4
on Chrome. But when I try what works for Vine url, doesn't work for my api url:
let videoUrl = NSURL(string: "http://myapi.app/player/vine.mp4")!
If I print(videoUrl)
, it gives - http://myapi.app/player/vine.mp4
.
Just to clarify again, this link is working on Chrome but not in the app. And all the videos used in the 3 approaches above are the same video.
Addition 1: Please note that I added this chunk to my info.plist
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>myapi.app</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSThirdPartyExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>
Also tried:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Addition 2: My route: $app->get('/player/{filename}', 'PlayerController@show')
and my Controller method:
public function show ($filename)
{
$this->playVid($filename, 'videos');
}
public function playVid($filename, $showType)
{
if (file_exists("../uploads/" . $showType . "/" . $filename)) {
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$type = finfo_file($finfo, "../uploads/" . $showType . "/" . $filename);
header("Content-Type: " . $type);
readfile("../uploads/" . $showType . "/" . $filename);
}
}
Video successfully plays in Chrome when I hit that route. But not in the Player demo app.
I found some code here https://github.com/piemonte/Player/blob/master/Source/Player.swift#L239-L245 to pause the video in viewDidDisappear
. Is there any way to resume the video when the view is visible again?
I am trying to make a video time bar with a slider. I realised I can achieve full duration of the video with self.player.maximumDuration
. However, how can I access current time of the video to link it to slider? I looked up the methods but couldn't find it. Thanks
Still investigating, but if use the player as VC for a peek, the playback is sporadic. Sometimes it plays super fast all the way through, then the next time it will play at normal speed but choppy. I'm still looking further into it, because I LOVE the player and it works perfectly everywhere else I'm using.
Hi,
Incase anyone is in immediate need of a function to find out the buffer available, I inserted the following into player.swift. Simply call it (i.e. self.player.bufferAvail
) to return the buffered NSTimeInterval. I am using it to decide whether to start playback (on slower connections).
Please note my swift is extremely basic and there is probably a better way of doing this which is a lot better (which I would love to hear!). Because of this I didn't want to put it as a PR.
Thanks
// return available buffer as NSTimeInterval
public var bufferAvail: NSTimeInterval {
// Check if there is a player instance
if ((player.currentItem) != nil) {
// Get current AVPlayerItem
var item: AVPlayerItem = player.currentItem
if (item.status == AVPlayerItemStatus.ReadyToPlay) {
var timeRangeArray: NSArray = item.loadedTimeRanges
var aTimeRange: CMTimeRange = timeRangeArray.objectAtIndex(0).CMTimeRangeValue
var startTime = CMTimeGetSeconds(aTimeRange.start)
var loadedDuration = CMTimeGetSeconds(aTimeRange.duration)
return (NSTimeInterval)(startTime + loadedDuration);
}
else {
return(CMTimeGetSeconds(kCMTimeInvalid))
}
}
else {
return(CMTimeGetSeconds(kCMTimeInvalid))
}
}
I want to add some control button like pause/play,fast forward and rewind, how to do? Should I add my own method in func handleTapGestureRecognizer(), or add the method in the player.swift?
Thanks a lot!
Is there a way to load the video onto the player from NSBundle? Maybe NSBundle.mainBundle().pathForResource(pathForResource...
( I'm a Newbie :) )
also, can't get the video to fill the view that i've added it to.
self.player.view.contentMode = .ScaleAspectFill
- this line seems to have no effect.
the purple is the view i've loaded the player into.
also... why the black edges?
please help. thanks :]
I have everything working pretty nicely with the reset i implemented, but i did start to realize that UITableViewCell
s and UICollectionView
s can be pretty tricky. I have a mixed media feed and i noticed my FPS dropped with or without video. I'm starting to profile now, and i'm realizing i'm doing some really stupid things. Like calling a reset method in prepareForReuse even if the cell isn't going to play a video.
I believe replaceCurrentItemWithPlayerItem
is done on the main and it's probably a bad idea to be constantly setting nil
on every prepareForReuse.
Basically what i need to be able to do is stop and hide the player on prepare for reuse, not tear the entire thing down. Then when cellForRow
is called it can then run through the standard setup when a new path
runs through the setter. The other problem is the cell has delegation methods to get notified on cellWillAppear
and didEndDisplayingCell
, and when they get this message they call the appropriate play/pause methods which will hijack the current cell as the Player
instance is still just sitting there. I could do a lot of juggling.
I guess it would be nice to somehow mark the controller that it needs a reset, but don't use the main thread for anything until a non nil value is passed to the setter. That means it would also have to ignore any calls between that time.
The combination of reusable views with tableView delegation methods makes this pretty hard.
Please add support for RTMp so that stream can be played..
Hi @piemonte !
I'm trying to use your lib with a TinderSimpleSwipeCards ( https://github.com/cwRichardKim/TinderSimpleSwipeCards )
This is the fastest video lib I've found.
However, when i create 16 card ( 16 Player ), the 17th is not displayed ... , and i dont know why.
But it works, if i press the home button, then i go back to the application... .
Any idea ?
If setUrl
is called before the view is loaded (i.e. checking for isViewLoaded
) the app crashes in the KVO method.
A simple solution is to store the url in a property and set it if isViewLoaded
and call setUrl
in the viewDidLoad
method if the stored url isn't nil:
override func setUrl(url: NSURL) {
self.url = url
if isViewLoaded() {
super.setUrl(url)
}
}
override func viewDidLoad() {
super.viewDidLoad()
if let url = self.url {
setUrl(url)
}
}
separate view controller?
Carthage version 0.8.0, attempting to install Player 0.0.6, on OS X 10.10.5:
Dependency "Player" has no shared framework schemes
I have a view controller on navigation stack. That view controller has a player and it is set as a PlayerDelegate. When view controller is removed from stack it is not deinitialized because player holds a strong reference to his delegate.
You should change your code to this:
public weak var delegate: PlayerDelegate?
public protocol PlayerDelegate: class {
...
}
How to set full screen player when rotate device ? Thx for support
And How to get current time item player
Currently it will install 0.0.5.
Dear friends,
could you help me which kind of format video files this can support?
Diego
Hi. I couldn't use the player-swift tag on SO. Wondering if you have any idea how I should be doing this. My SO question is here:
Basically, I have this swipe view and depending on where you are in that it will either show an image or a certain video.
I'm not sure where to create the Player() or how to properly remove it. When I create a new Player on every view I get a memory error. Creating one Player in viewWillAppear and changing the path when the swipe changes doesn't seem to work either.
Any thoughts?
Thanks :)
Is it possible to play the videos without a gap? Also, how can I minimize memory consumption by reusing the player?
func playVideo() {
videoPlayerController.videoPath = self.videoPath;
// present
self.addChildViewController(videoPlayerController);
playerView.addSubview(videoPlayerController.view);
videoPlayerController.didMoveToParentViewController(self);
// Start Video
videoPlayerController.playFromBeginning();
//videoPlayerController.playbackLoops = true;
}
func videoPlayerPlaybackDidEnd(videoPlayer: PBJVideoPlayerController!) {
videoPlayerController.removeFromParentViewController()
videoPlayerController.view.removeFromSuperview()
// setup next video and call self.playVideo()
}
This might be of some interest: https://github.com/katokichisoft/SimpleGaplessPlayer
i cant find a way to get the duration of the video
or the buffer loaded of the video
or the place the video is reproducing
or a way to advance the video to a place of the video
i use piemonte/Player to show video in my app but i found error in debugger
2015-11-15 17:58:30.238 summonerMenu[5361:200890] 17:58:30.238 ERROR: 177: timed out after 0.012s (180 180); mMajorChangePending=0
2015-11-15 17:58:43.652 summonerMenu[5361:200891] 17:58:43.651 ERROR: 177: timed out after 0.012s (1331 1332); mMajorChangePending=0
2015-11-15 17:58:48.789 summonerMenu[5361:200891] 17:58:48.789 ERROR: 177: timed out after 0.012s (1773 1774); mMajorChangePending=0
my Xcode is 7.1 IOS 9
Hey,
Videos don't seem to play on iOS9 GM, the player.view remains hidden. Any ideas?
Cheers!
AVAsset may expensive, can asset property be public to check and reuse?
also, make a method to set player by assert
I want to resize the player and add constraints to it, because I don't want it to use in fullscreen. I thought the best solution would be to put it into the Interface Builder and customize it there. How can I do that?
If you want, I can also add the question in StackOverflow. But right now it seems, that nobody asks question there, so I put it in here.
I’ve merged swift2.0
branch into master, and tagged the 0.0.7 version. @piemonte can you push the spec to CocoaPods? I don’t have the permission.
It would be nice to be able to show a progress indicator of the download for the video. Now I was wondering how hard this would be to implement as I was thinking of adding it in myself but could use some guidance from someone more familiar with the library.
Hello,
I just noticed, that there is no sound on the player, when using it on the iPhone. The sound is clearly enabled by default on the iPhone, and other apps work properly.
I used my own app and the sample project and on both there is no sound while the video is playing, BUT on the emulator everything works just fine.
What's the problem here?
It is hard to find which fill modes are supported when they are as strings.
self.player.fillMode = “AVLayerVideoGravityResizeAspect”
Could you please add the possible fill modes to the documentation or make them available with an enum?
I needed the ability to take a screenshot out of a the video at any point in time. Here's the function I added to accomplish it. Thought you might find it useful.
public func screenshot() -> UIImage? {
let imageGenerator: AVAssetImageGenerator = AVAssetImageGenerator(asset: self.asset)
if let time = self.player.currentItem?.currentTime() {
do {
let ref: CGImage = try imageGenerator.copyCGImageAtTime(time, actualTime: nil)
let viewImage: UIImage = UIImage(CGImage: ref)
return viewImage
} catch {
print("Something broke")
}
}
return nil
}
The example project does not provide a storyboard file, how would I set the player to play from a view in the storyboard with an iboutlet
Hey Patrick. First things first, thanks for an awesome library, really =)
Basically, I am trying to implement a Vine-like app which will have a video player inside each cell and other buttons for likes, sharing et cetera. What is your opinion about this and do you think that is this possible with the current design of the library itself?
I've installed the cocoa pods prerelease.
Successfully installed cocoapods-0.36.3
When I run pod install for the "Player" pod, it gives me this error
[!] Invalid Podfile file: undefined local variable or method `‘Player’' for #. Updating CocoaPods might fix the issue.
Also, are there any tutorials on how to integrate it with my app? I'm a complete noob to swift.
How can i record the rtsp player stream and save it locally ..
Is there any way to do it in this project..?
can i play youtube videos?
When the player shows up, it stops the music playing from Spotify and Music app. How can i prevent this?
Looking for help on making the video play inside of a custom view instead of having to be played in a view controller.
Any help is appreciated!
AVPlayer
has a muted
property that I would like to change, but I'm not allowed access to the player: AVPlayer
property of Player.
So my feature request (or general question of how to implement), either allow access directly to the AVPlayer
instance, or add a muted property to mute the audio of a video. 🙉
What do you think?
Can it display subtitle when playing? (SRT and ASS)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.