i built a very basic video player app in Xcode 4.3.2
i have 3 small videos and on my main menu i have 3 buttons. One button for each video
my code looks like this.....
- (IBAction)playMoviePressed1:(id)sender
{
NSString *path = [[NSBundle mainBundle]
pathForResource:#"HomeVideoOne" ofType:#"m4v"];
player = [[MPMoviePlayerViewController alloc]
initWithContentURL:[NSURL fileURLWithPath:path]];
[self presentMoviePlayerViewControllerAnimated:player];
}
And it repeats for videos 2 and 3. I would like to have a 4th button that played all 3 videos in order without stopping and having to select the next one. It's almost like having to play chapters in a movie one at a time.
Here's the kicker, I don't want to make any extra video files to add to the project size. So in other words the only way i am able to accomplish my goal so far is to edit all 3 videos into one .m4v file and import that to the project. But that is no good because it doubles my project size. I'd like to call on the existing files to play in one right after another with no break. I hope I didn't sound to repetitious.
Thank You
-ANthony
In this case you will need to use some more advanced API like AVQueuePlayer instead of a basic MPMoviePlayerController
Try look through the document here first http://developer.apple.com/library/ios/#documentation/AudioVideo/Conceptual/AVFoundationPG/Articles/02_Playback.html
You can always start another video whenever a video is finished playing. One way is to set your custom methods to be called to control the behavior when you create youMoviePlayerController:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(aMoviePlaybackComplete:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:youMoviePlayerController];
and then:
- (void)aMoviePlaybackComplete:(NSNotification*)notification
{
MPMoviePlayerController *moviePlayerController = [notification object];
if(urlIndex < yourUrlArray.count){
NSUrl* myUrl = [yourUrlArray objectAtIndex:urlIndex];
[moviePlayerController setContentURL:myUrl];
[moviePlayerController play];
urlIndex++;
}
else{
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:moviePlayerController];
[moviePlayerController.view removeFromSuperview];
[moviePlayerController release];
}
}
I'm assuming yourUrlArray is a pre-defined array of the urls of the movies you want to play and urlIndex is keeping count of the current movie being played. Of course, you'll have to tune this to your needs.
EDIT- For local files, you can form the NSUrl using bundle:
NSString *moviePath = [[NSBundle mainBundle] pathForResource:#"Movie" ofType:#"m4v"];
NSUrl* url = [NSURL fileURLWithPath:moviePath];
[yourUrlArray addObject:url];
and initialize the url array(yourUrlArray) and then continue as posted before.
Related
Im trying to play alasset MOV file from asset library. Does anyone use AVPlayerLayer?
if yes some hist will be great...
NSURL *myMovieURL = [NSURL URLWithString:_vUrl.absoluteString];
AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:myMovieURL options:nil];
AVPlayerItem *playerItem = [[AVPlayerItem alloc] initWithAsset:avAsset];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:playerItem];
self.player = [[AVPlayer alloc]initWithPlayerItem:playerItem];
[_playerlayer addObserver:self forKeyPath:#"readyForDisplay" options:0 context:nil];
((AVPlayerLayer *)[self layer]).bounds = ((AVPlayerLayer *)[self layer]).bounds;
[(AVPlayerLayer *)[self layer] setPlayer:_player];
_playerlayer = (AVPlayerLayer *)[self layer];
[_player seekToTime:kCMTimeZero];
You can't get the actual file-path from the AssetsLibrary because of sandboxing. However, you have various options to access/play the video file.
1) Query the URL of the Asset using the url method of ALAssetRepresentation and pass it to an instance of MPMoviePlayerController to play the video. This url starts with assets-library:// and is not a file-system url, but MPMoviePlayerController knows how to handle such an URL.
2) Get the video contents by using the getBytes:fromOffset:length:error: of ALAssetsRepresentation to save the video to your own app sandbox to play/edit/share it or use getBytes:fromOffset:length:error: to stream the video contents.
I'm getting this error mentioned in title while playing a video from internet.
- (void)viewDidLoad
{
NSString *urlAdress = [NSString stringWithFormat:#"http://www.dailymotion.com/video/x108t8t"];
//NSString *urlAdress = [[NSBundle mainBundle] pathForResource:#"video8" ofType:#"mp4"];in this case video plays.
NSURL *videoURL = [NSURL fileURLWithPath:urlAdress];
self.mpvc = [[MPMoviePlayerViewController alloc] initWithContentURL:videoURL];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlaybackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:nil];
self.mpvc.moviePlayer.movieSourceType = MPMovieSourceTypeStreaming;
//when using file in resources use MPMovieSourceTypeFile,when online then streaming
[self presentMoviePlayerViewControllerAnimated:mpvc];
[super viewDidLoad];
}
//and here is moviePlaybackDidFinish method
- (void)moviePlayBackDidFinish:(NSNotification *)notification
{
MPMoviePlayerController *theMovie = [notification object];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:theMovie];
[theMovie stop];
[theMovie.view removeFromSuperview];
NSLog(#" playback finish Called......");
}
this is whole code. i have went through most of tutorials,stackoverflow questions but could not get a single solution
Your URL is not correctly created for the case you quoted.
You are trying to play a remote stream, hence the URL needs to be a remote one.
Local file URLs are created using fileURLWithPath. Remote URLs are created using URLWithString.
Local File URL
NSURL *videoURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"video8" ofType:#"mp4"]];
Remote URL
NSURL *videoURL = [NSURL URLWithString:#"http://www.dailymotion.com/video/x108t8t"];
well this question seems a lot on stack overflow, i got a solution to this. most of the people facing same issue have right code but only problem is we forget to add dailymotion,vimeo frameworks. since they provide their own framework sdks
you can download them from links below and add them to your projects.
http://www.dailymotion.com/doc/api/sdk-objc.html
My objective is to put video files in a uipicker. I have added my video files names in an array and successfully extracting video file name and extensions but now my target is when user taps on row of picker then that selected video from the array will be passed to mpmovieplayercontroller object then that will play movie please let me know how can I write code to play another selected file after completion of one file i.e.in 1mpmovieplaybackfinished`
My code to play single video file is below.
Just let me know how can i play another video from an array:
-(IBAction)play:(id)sender
{
for (i = 0;i<[arrayofvideo count];i++) {<br /> NSLog(#"%d",i);
NSString *fullFileName = [NSString stringWithFormat:#"%#",[arrayofvideo objectAtIndex:i]];
NSString *filename = [fullFileName stringByDeletingPathExtension];
NSLog(#"%#",filename);
NSString *extension = [fullFileName pathExtension];
NSLog(#"%#",extension);
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle]
pathForResource:#"filename"
ofType:#"extension"]];
movieplayer = [[MPMoviePlayerController alloc]initWithContentURL:url];
movieplayer.movieSourceType = MPMovieSourceTypeFile;
movieplayer.controlStyle = MPMovieControlStyleDefault;
movieplayer.view.frame = CGRectMake(0,0,300,400);
[self.view addSubview:movieplayer.view];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(movieFinishedCallback:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:movieplayer];
//---play movie---
[movieplayer play];
}
-(void)movieFinishedCallback:(NSNotification*) aNotification
{
MPMoviePlayerController *player = [aNotification object];
[[NSNotificationCenter defaultCenter]
removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:player];
[player stop];
// self.view removeFromSuperView;
[self.view removeFromSuperview];
//call the play button again
// pls tell me what to write here to call play function
}
You need to restructure your code.
The code you posted builds a pathname from your array of video pathnames, and then uses a fixed filename of #"filename". That's not right.
You should write a method "playFileAtIndex" that finds a filename at a specific index and plays that file. I would suggest adding a BOOL parameter playMultipleVideos to the method. If the flag is true, the method would set up a movieFinishedCallback to increment the index and start the next movie playing.
Then make your button IBAction method set an index iVar to the selected row and invoke the playFileAtIndex method.
How can I play a YouTube video in an MPMoviePlayerController on the iPhone while avoiding going into fullscreen mode?
This question has been raised here: MPMoviePlayerController is playing YouTube video? and here: Play Youtube video in MPMoviePlayerController or play RTSP - 3GP link with answers claiming such functionality was impossible.
Yet this app, Deja, has exactly the functionality I would like: a seamless MPMoviePlayerController whose frame I have explicit control over. http://itunes.apple.com/app/deja/id417625158
How is this done!?
add this sample into you project
instantiate YoutubeStreamPathExtractorTest
invoke test method of YoutubeStreamPathExtractorTest instance.
Follow logs and be happy
#import "AFHTTPRequestOperationManager.h"
#import <MediaPlayer/MediaPlayer.h>
typedef void (^CallbackBlock)(NSArray* result, NSError* error);
static NSString* const kYouTubeStreamPathPattern = #"\\\"url_encoded_fmt_stream_map\\\\\":.*?url=(.*?)\\\\u0026";
#interface YoutubeStreamPathExtractorTest : NSObject
- (void)test;
- (void)youtubeURLPath:(NSString*)youtubeURLPath extractStreamURLPathsWithCallback:(CallbackBlock)callback;
#end
#implementation YoutubeStreamPathExtractorTest
- (void) test {
NSString* path = #"http://www.youtube.com/watch?v=TEV5DZpAXSw";
[self youtubeURLPath:path extractStreamURLPathsWithCallback:^(NSArray *result, NSError *error) {
if (error){
NSLog(#"extracting error:%#",[error localizedDescription]);
}
for(NSString* streamURLPath in result) {
NSLog(#"streamURLPath:%#",streamURLPath);
/*
NSURL* url = [NSURL URLWithString:streamURLPath];
MPMoviePlayerController* mpMoviePlayerController_ = [[MPMoviePlayerController alloc] initWithContentURL:url];
mpMoviePlayerController_.controlStyle = MPMovieControlStyleDefault;
[mpMoviePlayerController_ play];
*/
}
}];
}
- (void)youtubeURLPath:(NSString*)youtubeURLPath extractStreamURLPathsWithCallback:(CallbackBlock)callback {
__block NSMutableArray* resultArray = [NSMutableArray new];
AFHTTPRequestOperationManager* manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:nil];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:#"text/html", nil];
[manager GET:youtubeURLPath
parameters:nil
success:^(AFHTTPRequestOperation* operation, id responseObject) {
NSData* data = (NSData*)responseObject;
NSString* string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSError* error = nil;
NSRegularExpression* expression = [NSRegularExpression regularExpressionWithPattern:kYouTubeStreamPathPattern
options:NSRegularExpressionCaseInsensitive
error:&error];
NSRange range = NSMakeRange(0,[string length]);
NSArray* matches = [expression matchesInString:string options:0 range:range];
for(NSTextCheckingResult* checkingResult in matches) {
if ([checkingResult numberOfRanges]>1){
NSString* resultStr = [string substringWithRange:[checkingResult rangeAtIndex:1]];
//remove extra slashes
[resultArray addObject:[resultStr stringByReplacingOccurrencesOfString:#"\\" withString:#""]];
}
}
if (callback) {
callback(resultArray,error);
}
} failure:^(AFHTTPRequestOperation* operation, NSError* error) {
if (callback) {
callback(resultArray, error);
}
}];
}
#end
MPMoviePlayerController does not support the playback of YouTube SWF (Flash) video, period.
That app you are mentioning actually plays progressively downloaded files in MP4 format which YouTube also offers for some of its content. This actually is a violation of Apple's guidelines as it will (and does) exceed the maximum amount of progressive download per app per timeframe. I am surprised it got through the iTunes approval.
Warning: iOS apps submitted for distribution in the App Store must
conform to these requirements. If your app delivers video over
cellular networks, and the video exceeds either 10 minutes duration or
5 MB of data in a five minute period, you are required to use HTTP
Live Streaming. (Progressive download may be used for smaller clips.)
If your app uses HTTP Live Streaming over cellular networks, you are
required to provide at least one stream at 64 Kbps or lower bandwidth
(the low-bandwidth stream may be audio-only or audio with a still
image).
These requirements apply to iOS apps submitted for distribution in the
App Store for use on Apple products. Non-compliant apps may be
rejected or removed, at the discretion of Apple.
So your task boils down to the question on how to get the MP4 URL of a video offered through YouTube. That part is really tricky and nicely solved by Deja. Just use a packet sniffer and you will see that it actually creates a local server that feeds MPMoviePlayerController.
try this code:
NSString *urlStr=[Your url is here];
NSURL *url = [NSURL fileURLWithPath:urlStr];
MPMoviePlayerController* moviePlayer = [[MPMoviePlayerController alloc]initWithContentURL:url];
[self.view addSubview:moviePlayer.view];
moviePlayer.view.frame = CGRectMake(set frame is here);
[moviePlayer play];
[moviePlayer setFullscreen:NO animated:YES];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish)
name:MPMoviePlayerPlaybackDidFinishNotification
object:nil];
I guess it is against Youtube ToS but you can use this code here:
https://github.com/larcus94/LBYouTubeView
It is simple to use and works like a charm!
Use UIWebView. Copy HtML code video in youtube.
UIWevView* movie = [UIWebView alloc] initWithFrame:CGRectMake(0,0,320,460)];
NSString* urlString = #"past HTML code";
[self.webView loadHTMLString:urlString baseURL:nil];
[self.view addSubview:movie];
I need to play a movie already synchronised from iTunes to Apples 'Movies' App on a iPad, in a view.
I can play a movie from the bundle using MPMoviePlayerController OK. I can get a media Item of all movies (NSArray of MPMediaItem's using MPMediaQuery). However the MPMoviePlayerController only accepts an NSURL - not an MPMediaItem.
So, how can I play a movie when all I have is a MPMediaItem of the movie? Is there another object other than MPMoviePlayerController that does this? Several posts explain how to 'get' a media item but not how to 'set' an item.
Any help is greatly appreciated.
each MPMediaItem has an URL which can be accessed with valueForProperty:.
I don't know if you can use that to play it in MPMoviePlayerController though. In theory it should work.
NSURL *url = [mediaItem valueForProperty:MPMediaItemPropertyAssetURL];
EDIT: Looks like it's not possible to use that.
MPMediaItemPropertyAssetURL
A URL pointing to the media item, from which an AVAsset object (or other URL-based AV Foundation object) can be created, with any options as desired. Value is an NSURL object.
The URL has the custom scheme of ipod-library. For example, a URL might look like this:
ipod-library://item/item.m4a?id=12345
Usage of the URL outside of the AV Foundation framework is not supported.
from: General Media Item Property Keys
Try this
NSURL *url = [mediaItem valueForProperty:MPMediaItemPropertyAssetURL];
MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentURL: url];
[player prepareToPlay];
[player.view setFrame: myView.bounds]; // player's frame must match parent's
[myView addSubview: player.view];
[player play];
i think this should work..
MPMediaItem is inherited from MPMediaEntity which has the method valueForProperty: