I have an ESP8266-CAM which I connect to my WiFi and stream it out. I have it so I can go onto any browser anywhere and type in the address http://xxx.xxxxx.xxxx.xx.xx/xxxxx/x and it will play. I have it working in a Blynk app also using this address. I would like to include it in an iPhone app I am building.
I have the following code to play the stream.
#import "ViewController.h"
#import <AVKit/AVKit.h>
#import <AVFoundation/AVFoundation.h>
#interface ViewController ()
#property (nonatomic, strong) AVPlayer *player;
#property (nonatomic,strong) AVPlayerItem * playerItem;
#property (nonatomic, strong )AVPlayerLayer *avPlayerLayer;
-(IBAction)Turnon:(id)sender;
- (void)viewDidLoad {
[super viewDidLoad];
}
-(void) startplayer
{
NSURL *url = [[NSURL alloc]initWithString:#"xxxxxxxxxxx/xxxxx/1"];
AVPlayerItem * playerItem= [AVPlayerItem playerItemWithURL:url];
self.player = [AVPlayer playerWithPlayerItem:playerItem];
self.player.allowsExternalPlayback= YES;
self.avPlayerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
self.avPlayerLayer.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
//self.player.automaticallyWaitsToMinimizeStalling = false;
self.avPlayerLayer.videoGravity = AVLayerVideoGravityResizeAspect;
//I HAVE TRIED THIS AT DIFFERENT LAYERS
[self.view.layer insertSublayer:self.avPlayerLayer atIndex:0
];
//THIS DOES PRINT IN LOG
NSLog(#"this is getting played");
[self.player.currentItem addObserver:self
forKeyPath:#"status"
options:0
context:nil];
}
-(IBAction)showVideo:(id)sender;{
[self startplayer];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if (object == self.player.currentItem && [keyPath isEqualToString:#"status"])
{
NSLog(#"This is being called");
[self.player play];
self.player.rate = 1.0;
if (self.player.currentItem.status == AVPlayerStatusReadyToPlay)
{
//THIS IS ALSO BEING PRINTED IN LOG
NSLog(#"This is being called");
[self.player play];
self.player.rate = 1.0;
}
}
}
#end
Even though when I press the button to showVideo and the log show all parts are activated, no screen shows up. Does anyone have any ideas why this is happening?
I have figured out that the camera is sending out a steam of mjpeg images that work in the video player in Blynk but apparently Apple doesn't use. I think this is the problem in that the player can't recognize or decode the format so no image nothing.
Does anyone have an idea of how to play an mjpeg image streams
So I couldn't get the video to stream using AVPlayer, but by creating a WKWebView and opening the server in it I got the live video to play. Only thing is getting it to resize bigger one can see the details better. But at least it works. Here is the code.
#import <WebKit/WKWebViewConfiguration.h>
WKWebViewConfiguration *theConfiguration = [[WKWebViewConfiguration alloc] init];
self.webView = [[WKWebView alloc] initWithFrame:CGRectMake(self.view.center.x-(320/2),self.view.center.y-(240/2), 320, 240) configuration:theConfiguration];
NSURL *nsurl=[NSURL URLWithString:#"http://70.176.81.136:81/CFC878/1"];
NSURLRequest *nsrequest=[NSURLRequest requestWithURL:nsurl];
[_webView loadRequest:nsrequest];
[self.view insertSubview:self.webView atIndex:14];
Related
I've noticed that AVPlayerItemDidPlayToEndTimeNotification is occasionally sent when the network is deactivated and the video cannot continue playing. This is despite the video not having completed.
This can be reproduced with the following code:
#import "ViewController.h"
#import
#interface ViewController ()
#property AVPlayerItem *item;
#property AVPlayer *player;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSURL *url = [NSURL URLWithString:#"https://video-dev.github.io/streams/x36xhzz/x36xhzz.m3u8"];
self.item = [[AVPlayerItem alloc] initWithURL: url];
self.player = [[AVPlayer alloc] initWithPlayerItem:self.item];
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
playerLayer.frame = self.view.bounds;
[NSNotificationCenter.defaultCenter addObserver:self selector:#selector(handleNotification:) name:AVPlayerItemDidPlayToEndTimeNotification object:self.item];
[self.view.layer addSublayer:playerLayer];
[self.player addObserver:self forKeyPath:#"status" options:0 context:nil];
[[AVAudioSession sharedInstance]
setCategory: AVAudioSessionCategoryPlayback
error: nil];
[self.player play];
NSLog(#"Playing");
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
change:(NSDictionary *)change context:(void *)context {
if (object == self.player && [keyPath isEqualToString:#"status"]) {
}
}
-(void)handleNotification:(NSNotification*)notification {
NSLog(#"%#", notification.name.debugDescription);
NSLog(#"HandleNotification called at:%lld seconds. Duration on player is:%lld seconds", self.player.currentTime.value/self.player.currentTime.timescale, self.item.duration.value/self.item.duration.timescale);
}
#end
Reproduction steps are:
1. Run the app and let the video play for around 40s.
2. Kill the network on the device.
AVPlayerItemDidPlayToEndTimeNotification is fired and written to the log.
Is there any reason why I should expect this to happen? And if so, how can I distinguish between an end of play event and a failure to continue playback due to lack of buffered content?
I found same issue from AVPlayer's notification.
When AVPlayerItemFailedToPlayToEndTime is trigged, I check AVPlayerItem's position from the end.
Code sample from ModernAVPlayer library:
Delay is about 10 seconds.
Snippet of my code. It's *.m file of HomeController:
#interface HomeController ()
#property(nonatomic, strong) AVPlayerViewController *playerViewController;
#implementation HomeController
- (void)viewDidLoad
{
[super viewDidLoad];
...
self.playerViewController = [[AVPlayerViewController alloc] init];
}
- (IBAction)watchDemoToggle:(id)sender {
NSURL *url = [NSURL URLWithString:#"http://blahblahblah.com/demo.mp4"];
AVURLAsset *asset = [AVURLAsset assetWithURL: url];
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:asset];
if(playerItem)
{
AVPlayer *player = [[AVPlayer alloc] initWithPlayerItem:playerItem];
self.playerViewController.player = player;
[self.playerViewController.player addObserver:self forKeyPath:#"status" options:0 context:nil];
[self.playerViewController setShowsPlaybackControls:NO];
[self presentViewController:self.playerViewController animated:YES completion:^{
[self.playerViewController.player play];
self.playerViewController.showsPlaybackControls = YES;
}];
}
}
#pragma mark - KVO
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
if ([keyPath isEqualToString:#"status"]) {
AVPlayerStatus status = [change[NSKeyValueChangeNewKey] integerValue];
NSLog(#"status = %ld", (long)status);
}
}
I added KVO and got result that after click play player status is AVPlayerStatusUnknown. After that it is not changing despite the fact that the video is reproducing.
Does anyone have any idea?
set automaticallyWaitsToMinimizeStalling property of AVPlayer to false in order to start playback immediately.
AVPlayer *player = [[AVPlayer alloc] initWithPlayerItem:playerItem];
player.automaticallyWaitsToMinimizeStalling = false;
But if sufficient content is not available for playing then player might stall.
for more details please refer this Apple documentation.
avplayer
So I am building a custom video player using AVFoundation - AVPlayer and AVPlayerLayer.
Currently, all I want the player to do is play a video in the asset library with a hardcoded url to that video. I would like this to be contained in a SubClass of UIView so I can use it all around my app.
Here is my code so far:
CUPlayer.h:
#interface CUPlayer : UIView
{
AVPlayer *player;
AVPlayerLayer *playerLayer;
AVPlayerItem *item;
NSURL *url;
}
#property(nonatomic) UIViewAutoresizing autoresizingMask;
#end
CUPlayer.m:
#implementation CUPlayer
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
// Initialization code
self.backgroundColor = [UIColor redColor];
[self setupURL];
}
return self;
}
-(void)setupURL
{
NSLog(#"URL setting up");
NSString *string = #"assets-library://asset/asset.mov?id=0A937F0D-6265-452D-8800- 1A760E8E88B9&ext=mov";
url = [[NSURL alloc] initFileURLWithPath: string];
[self setupPlayerForURL];
}
-(void)setupPlayerForURL
{
AVAsset *asset = [AVURLAsset URLAssetWithURL:url options:nil];
item = [AVPlayerItem playerItemWithAsset:asset];
player = [AVPlayer playerWithPlayerItem:item];
[player addObserver:self forKeyPath:#"status" options:0 context:nil];
playerLayer = [AVPlayerLayer playerLayerWithPlayer:player];
//player.actionAtItemEnd = AVPlayerActionAtItemEndNone;
[self.layer addSublayer:playerLayer];
playerLayer.frame = CGRectMake(0, 0, 200, 200);
//[playerLayer setBackgroundColor:[UIColor greenColor].CGColor];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if (object == player && [keyPath isEqualToString:#"status"]) {
if (player.status == AVPlayerStatusFailed) {
NSLog(#"AVPlayer Failed");
} else if (player.status == AVPlayerStatusReadyToPlay) {
NSLog(#"AVPlayer Ready to Play");
[player play];
} else if (player.status == AVPlayerItemStatusUnknown) {
NSLog(#"AVPlayer Unknown");
}
}
}
And then I am calling this from the View Controller:
CUPlayer *cuPlayer = [[CUPlayer alloc]initWithFrame:CGRectMake(0, 0, 250, 250)];
[self.view addSubview:cuPlayer];
This complies but just give me a red square without the video playing. The URL to the local file is definitely correct. I can get it working if I hold all the code in the view controller and run the play in -(void)viewDidLayoutSubviews.
Help would very much be appreciated, I have read all the documentation multiple times trying to work this thing out.
Tom
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];
}
Hi i have created app for ipad , it has an video files in resource folder and it plays when the user click play button.
It works for first time user clicks play button but when user plays subsequent times of video file.The issues occurs that is the video is not play only audio is playing.These issues occurs not randomly but some more times it will occurs.
One more thing at the time of issue occurs (Video is not playing ) , when i click the wo-arrow icons located at the bottom right corner of the player the movie goes to full screen and it shows video .At the time video is playing.
Can any one help me ?
Here is my sample code
MPMoviePlayerController *moviePlayer;
}
#property (readwrite, retain) MPMoviePlayerController *moviePlayer;
#synthesize moviePlayer;
- (void)viewDidLoad {
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(movieFinishedCallback:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:self.moviePlayer];
[super viewDidLoad];
}
-(IBAction)PlayBtnPressed:(id)sender
{
NSURL *movieURL;
NSString *moviePath = [[NSBundle mainBundle] pathForResource:#"title" ofType:#"mp4"];
movieURL = [NSURL fileURLWithPath:moviePath];
// Initialize a movie player object with the specified URL
MPMoviePlayerController *mp = [[MPMoviePlayerController alloc] initWithContentURL:movieURL];
if (mp)
{
// save the movie player object
self.moviePlayer = mp;
[mp release];
UIInterfaceOrientation orientation = [[UIDevice currentDevice]orientation];
[self shouldAutorotateToInterfaceOrientation:orientation];
// Play the movie!
[self.view addSubview:self.moviePlayer.view];
[self.moviePlayer play];
}
}
- (void) movieFinishedCallback:(NSNotification*) aNotification {
NSLog(#"movieFinishedCallback aNotification");
MPMoviePlayerController *player = [aNotification object];
[[NSNotificationCenter defaultCenter]
removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:player];
[player stop];
[player.view removeFromSuperview];
}
Thanks in advance ........
Looks like the movieplayer is not getting released until after you've allocated a second one on the same movie file:
self.moviePlayer = mp;
retains it, but the movie finished part doesn't do a
self.moviePlayer = nil;
Could be that's causing you problems.