My issue is the following when I get the file from the bundle I don't have any issue to play it with the AVPlayer.
But when I use the file sharing with iTunes and I try to play the file from the document folder and it doesn't work.
.h
#import <AVFoundation/AVFoundation.h>
#import <AVKit/AVKit.h>
#property (strong, nonatomic) AVPlayerViewController *videoController;
#property (strong, nonatomic) AVPlayer *player;
.m
The url get is the following (already try with mov , mp4 and mpg) : file:///var/mobile/Containers/Data/Application/D35C60F9-6656-421C-8798-FB938321C86E/Documents/foo.mpg
- (IBAction)playVideo:(id)sender {
if(videoArray && [videoArray count] >= 1){
if(!self.videoController){
self.videoController = [AVPlayerViewController new];
}
// create an AVPlayer
NSURL *videoURL = [NSURL fileURLWithPath:videoArray[0]];
//self.player = [AVPlayer playerWithURL:videoURL];
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:videoURL];
self.player = [AVPlayer playerWithPlayerItem:playerItem];
self.videoController.player = self.player;
[self.videoController.player play];
//listen for end
//[self.videoController.player addObserver:self forKeyPath:#"status" options:0 context:0];
// show the view controller
self.videoController.showsPlaybackControls = false;
self.videoController.view.frame = self.view.frame;
[self addChildViewController:self.videoController];
[self.view addSubview:self.videoController.view];
}
}
Related
Hi I have an iOS Objective-C app which does not use Storyboards (It uses XIB files)
I want to add a splash screen to play a video so I added a new Coca Touch Class derived from UIViewController (And ticked 'Also create XIB file).
I have swapped this class as my new main screen and it loads properly but does not play the video. I have added the AVFoundation framework etc so that is not an issue.
Here is my code.
.h File
#import <UIKit/UIKit.h>
#interface VideoIntroViewController : UIViewController
#property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;
#end
.m file
import <AVFoundation/AVFoundation.h>
static const float PLAYER_VOLUME = 0.0;
#interface VideoIntroViewController ()
#property (nonatomic) AVPlayer *player;
#property (weak, nonatomic) IBOutlet UIView *playerView;
#end
#implementation VideoIntroViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self createVideoPlayer];
}
- (void)createVideoPlayer
{
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"welcome_video" ofType:#"mp4"];
NSURL *url = [NSURL fileURLWithPath:filePath];
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:url];
self.player = [AVPlayer playerWithPlayerItem:playerItem];
self.player.volume = PLAYER_VOLUME;
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
playerLayer.videoGravity = UIViewContentModeScaleToFill;
playerLayer.frame = self.playerView.layer.bounds;
[self.playerView.layer addSublayer:playerLayer];
[self.player play];
}
The screen launched but no video plays.
What could be going wrong?
Try this code:
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"welcome_video" ofType:#"mp4"];
NSURL *url = [NSURL fileURLWithPath:filePath];
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:url];
self.player = [AVPlayer playerWithPlayerItem:playerItem];
CALayer *superlayer = self.playerView.layer;
self.player.volume = 1.0;
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;// you can also use AVLayerVideoGravityResizeAspect to clip video to view's bound
playerLayer.frame = self.playerView.layer.bounds;
[superlayer addSublayer:playerLayer];
[self.player seekToTime:kCMTimeZero];
[self.player play];
I have checked it for some other video file and it is working fine.
In my main XIB file I did not have a View control placed on it.
When I placed a View Control and then CTL+Right clicked and connected it to my playerView it then played the video.
I am trying to play a video which is stored on my device trying both AVPlayer and MPMoviePlayerController.
Video URl is: file:///var/mobile/Containers/Data/Application/73695F3E-9351-447B-BB8A-0B4A62CE430F/Documents/08-03-201711:48:50.3gp. Now the problem is I get blank screen.
AVPlayer *player = [AVPlayer playerWithURL:fileURL];
AVPlayerViewController *playerViewController = [AVPlayerViewController new];
[player pause];
[player play];
playerViewController.player = player;
[self addChildViewController: playerViewController];
[self.view addSubview: playerViewController.view];
//[playerViewController.player play];//Used to Play On start
[self presentViewController:playerViewController animated:YES completion:nil];
I think the problem is in link. What I am doing is getting local directory link and append name with that link.
I will you good solution.It works perfectly.
ViewController.h
#import <UIKit/UIKit.h>
#import <AVKit/AVKit.h>
#interface ViewController : UIViewController
#property (strong, nonatomic) AVPlayerViewController *playerViewController;
- (IBAction)actionPlayVideo:(id)sender;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController (){
NSURL *vedioURL;
}
#end
#implementation ViewController
#synthesize playerViewController;
- (IBAction)actionPlayVideo:(id)sender{
NSString *fullpath = [[self documentsDirectory] stringByAppendingPathComponent:#"yourdate.3gp"];
vedioURL =[NSURL fileURLWithPath:fullpath];
AVPlayerItem* playerItem = [AVPlayerItem playerItemWithURL:vedioURL];
AVPlayer* playVideo = [[AVPlayer alloc] initWithPlayerItem:playerItem];
playerViewController = [[AVPlayerViewController alloc] init];
playerViewController.player = playVideo;
playerViewController.player.volume = 0;
playerViewController.view.frame = self.view.bounds;
[self.view addSubview:playerViewController.view];
[playVideo play];
}
-(NSString *)documentsDirectory{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
return documentsDirectory;
}
EDIT: MPMoviePlayerController is Deprecated Now. So I have used AVPlayerViewController. and written the following code:
NSURL *videoURL = [NSURL fileURLWithPath:filePath];
//filePath may be from the Bundle or from the Saved file Directory, it is just the path for the video
AVPlayer *player = [AVPlayer playerWithURL:videoURL];
AVPlayerViewController *playerViewController = [AVPlayerViewController new];
playerViewController.player = player;
//[playerViewController.player play];//Used to Play On start
[self presentViewController:playerViewController animated:YES completion:nil];
Please do not forget to import following frameworks:
#import <AVFoundation/AVFoundation.h>
#import <AVKit/AVKit.h>
You can use MPMoviePlayerController to play local file.
Add Mediaplayer framework and do #import in your viewController.
Drag and drop your video file you created on desktop into the xcode.
Get the path of the local video.
NSStringthePath=[[NSBundle mainBundle] pathForResource:#"yourVideo" ofType:#"MOV"];
NSURLtheurl=[NSURL fileURLWithPath:thePath];
Initialize the moviePlayer with your path.
self.moviePlayer=[[MPMoviePlayerController alloc] initWithContentURL:theurl];
[self.moviePlayer.view setFrame:CGRectMake(40, 197, 240, 160)];
[self.moviePlayer prepareToPlay];
[self.moviePlayer setShouldAutoplay:NO]; // And other options you can look through the documentation.
[self.view addSubview:self.moviePlayer.view];
To control what is to be done after playback:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(playBackFinished:) name:MPMoviePlayerPlaybackDidFinishNotification object:moviePlayer];
//playBackFinished will be your own method.
EDIT 2: To handle completion for AVPlayerViewController rather than MPMoviePlayerController, use the following...
AVPlayerItem *playerItem = player.currentItem;
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(playBackFinished:) name:AVPlayerItemDidPlayToEndTimeNotification object:playerItem];
In this example, I dismiss the AVPlayerViewController after completion:
-(void)playBackFinished:(NSNotification *) notification {
// Will be called when AVPlayer finishes playing playerItem
[playerViewController dismissViewControllerAnimated:false completion:nil];
}
It may happen because of your file url is incorrect.
Try below codes to get the path of your answer.
If you have the video in your mac, then copy it in to your project firstly, just drug it to Xcode.
NSString *filepath = [[NSBundle mainBundle] pathForResource:#"08-03-201711:21:67" ofType:#"3gp"];
NSURL *fileURL = [NSURL fileURLWithPath:filepath];
And use this path to AVPlayer
AVPlayer *player = [AVPlayer playerWithURL:fileURL];
AVPlayerViewController *playerViewController = [AVPlayerViewController new];
[player pause];
[player play];
playerViewController.player = player;
[self addChildViewController: playerViewController];
[self.view addSubview: playerViewController.view];
**As I review your code, a blank screen may caused by you adding AVPlayer it into layer but not as subview/childviewcontroller. So try my code!
I have implemented avplayer programatically.
#interface showAskUsVideo ()
{
AVURLAsset *asset;
AVPlayerItem *item;
}
#property (strong, nonatomic) AVPlayer *player;
-(void)viewWillAppear:(BOOL)animated
{
[self playVideo];
}
-(void)playVideo {
[playerViewController.view setFrame:CGRectMake(37, 80 ,495,220)];
asset = [AVURLAsset assetWithURL: url];
item = [AVPlayerItem playerItemWithAsset: asset];
_player = [[AVPlayer alloc] initWithPlayerItem: item];
playerViewController.showsPlaybackControls = NO;
playerViewController.player = _player;
[item addObserver:self forKeyPath:#"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:nil];
[_player addObserver:self forKeyPath:#"rate" options:0 context:nil];
[self.view addSubview:playerViewController.view];
}
But when I select deployment target 10.0 then its working fine. But for iOS 8.0 to 9.3 only PlaybackControls is seen on screen not video.
What need to change in my code?
Is playerViewController part of the view controller hierarchy? If not, that could explain it. Try adding it as a child view controller of your view controller:
[self addChildViewController:playerViewController];
[self.view addSubview:playerViewController.view];
Try like that: Add to .m
#property (nonatomic, retain)AVPlayer *player;
#property (weak, nonatomic) IBOutlet AVPlayerClass *playerView;
(playerView is your view where you want to show it)
NSURL *url = [[NSBundle mainBundle]URLForResource:#"video_name" withExtension:#"mp4"];
_player = [AVPlayer playerWithURL:url];
playerLayer = [AVPlayerLayer playerLayerWithPlayer:_player];
playerLayer.frame = _playerView.bounds;
playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[_playerView.layer insertSublayer:playerLayer atIndex:0];
_player.actionAtItemEnd = AVPlayerActionAtItemEndNone;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:[_player currentItem]];
[_player play];
-(void)playerItemDidReachEnd:(NSNotification *)notification{
AVPlayerItem *p = [notification object];
[p seekToTime:kCMTimeZero];
}
If you using a ViewController for your player. The best practice is presentingViewController
[self presentViewController:playerViewController animated:YES completion:nil];
if you using xib
PlayerViewController *vc = [[PlayerViewController alloc]
initWithNibName:#"PlayerViewController" bundle:nil];
[self.view addSubview:[vc view]];
This is my code,
#interface ViewController ()
{
AVPlayer *avPlayer;
}
#end
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
UIView *containerView = [[UIView alloc] initWithFrame:self.view.frame];
NSString *filepath = [[NSBundle mainBundle] pathForResource:#"TestVideo" ofType:#"mp4"];
AVAsset *asset = [AVAsset assetWithURL:[NSURL fileURLWithPath:filepath]];
AVPlayerItem *playerItem = [[AVPlayerItem alloc] initWithAsset:asset];
avPlayer = [AVPlayer playerWithPlayerItem:playerItem];
AVPlayerLayer *avPlayerLayer = [AVPlayerLayer playerLayerWithPlayer:avPlayer];
avPlayerLayer.frame = self.view.frame;
[containerView.layer addSublayer:avPlayerLayer];
[self.view addSubview:containerView];
[avPlayer play];
}
That really shouldn't work on any iOS version as
AVPlayer *avPlayer = [AVPlayer playerWithPlayerItem:playerItem];
is going out of scope and being deallocated at the end of viewDidAppear.
You should assign the AVPlayer to a class member variable, to stop this happening.
Otherwise there may be a problem with the video file.
Your AVPlayer item needs a strong reference as it sets to nil automatically
Please change
#interface ViewController ()
{
AVPlayer *avPlayer;
}
#end
to this
#interface ViewController ()
#property (strong, nonatomic) AVPlayer *avPlayer;
#end
and change all avPlayer reference to self.avPlayer
I hope this helps.
I'm trying to create an iOS/iPhone radio app using Xcode 4.5.2.
I wanted to stream #"http://xx.xxxxxxx.com/8111/radio.m3u" with play, pause, volume control and able to play on background feature/multitasking.
I've added AVFoundation, Mediaplayer and AudioToolBox frameworks thus far. I've added play, pause and slider objects to xib.
ViewController.h
#interface ViewController : UIViewController
#property (strong,nonatomic) MPMoviePlayerController *myPlayer;
#property (weak, nonatomic) IBOutlet UISlider *myslider;
- (IBAction)playButtonPressed;
- (IBAction)myslider:(id)sender;
#end
ViewController.m
#import "ViewController.h"
#import <MediaPlayer/MediaPlayer.h>
#interface ViewController ()
{
UISlider *volumeSlider;
}
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
UIBackgroundTaskIdentifier newTaskId = UIBackgroundTaskInvalid;
newTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:NULL];
}
- (IBAction)playButtonPressed;
{
NSString *urlAddress = #"http://xxxxxxx.com/8111/listen.m3u";
NSURL *url = [NSURL URLWithString:urlAddress];
MPMoviePlayerController *player = [[MPMoviePlayerController alloc]initWithContentURL:url];
player.movieSourceType = MPMovieSourceTypeStreaming;
[player prepareToPlay];
self.myPlayer = player;
[self.view addSubview:self.myPlayer.view];
[self.myPlayer play];
}
- (IBAction)stopButtonPressed;
{
[self.myPlayer stop];
}
- (IBAction)myslider:(id)sender
{
MPVolumeView *volumeView = [[MPVolumeView alloc] initWithFrame: CGRectMake(10, 10, 200, 40)];
[volumeSlider addSubview:volumeView];
[volumeView sizeToFit];
}
There are Two way to achieve this.
You can directly load you URL in UIWebView and it will properly.
You can also use MPMoviePlayerController.
Create a "MPMoviePlayerController *player" as a strong object in your ViewController.
So you code would look something like below:
#interface ViewController ()
{
UISlider *volumeSlider;
MPMoviePlayerController *player;
}
#end
- (IBAction)playButtonPressed;
{
NSString *urlAddress = #"http://xxxxxxx.com/8111/listen.m3u";
NSURL *url = [NSURL URLWithString:urlAddress];
if(nil != player)
{
player = nil; // Alternatively you can stop and restart with the different stream.
}
player = [[MPMoviePlayerController alloc]initWithContentURL:url];
player.movieSourceType = MPMovieSourceTypeStreaming;
[player prepareToPlay];
self.myPlayer = player;
[self.view addSubview:self.myPlayer.view];
[self.myPlayer play];
}