Im trying to stream a video from youtube when the user select a row in my tableview,
heres the code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *videoURLString = [self.listaVideos objectAtIndex:[indexPath row]];
NSURL *videoURL = [NSURL URLWithString:videoURLString];
self.theMovie = [[MPMoviePlayerViewController alloc] initWithContentURL:videoURL];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:[self.theMovie moviePlayer]];
[self.view addSubview:self.theMovie.view];
[self.theMovie setWantsFullScreenLayout:NO];
[self presentMoviePlayerViewControllerAnimated:theMovie];
[[self.theMovie moviePlayer] play];
}
-(void)moviePlayBackDidFinish:(NSNotification*)notification
{
NSLog(#"ENded");
}
And the error: Unbalanced calls to begin/end appearance transitions for <MPMoviePlayerViewController: 0x7a256a0>.
Try removing
[self.view addSubview:self.theMovie.view];
You appear to be adding it the view, then presenting it. (If you don't want to present it, remove that line instead)
MPMoviePlayerViewController can't stream YouTube videos.
Oh, also what Amit Shah said as well (removing the addSubview: will take care of the unbalanced calls, but not the inability to play videos).
Below is the code which the video from youtube url.If you are really looking for streaming the Video from Youtube then, rely on below code it's very easy & event you don't have to take much care of Event Handling , buffering etc...
#interface VideoPlayerContrl : UIViewController {
IBOutlet UIWebView *youtubeVideo;
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
NSString *htmlString = #"<html><head>\n"
"<meta name = \"viewport\" content = \"initial-scale = 1.0, user-scalable = no, width = 212\"/></head>\n"
"<body style=\"background:#F00;margin-top:0px;margin-left:0px\">\n"
"<div><object width=\"212\" height=\"172\">\n"
"<param name=\"movie\" value=\"http://www.youtube.com/v/oHg5SJYRHA0&f=gdata_videos&c=ytapi-my-clientID&d=nGF83uyVrg8eD4rfEkk22mDOl3qUImVMV6ramM\"></param>\n"
"<param name=\"wmode\" value=\"transparent\"></param>\n"
"<embed src=\"http://www.youtube.com/v/oHg5SJYRHA0&f=gdata_videos&c=ytapi-my-clientID&d=nGF83uyVrg8eD4rfEkk22mDOl3qUImVMV6ramM\"\n"
"type=\"application/x-shockwave-flash\" wmode=\"transparent\" width=\"247\" height=\"178\"></embed>\n"
"</object></div></body></html>\n";
[youtubeVideo loadHTMLString:htmlString baseURL:[NSURL URLWithString:#"https://s3.amazonaws.com/adplayer/colgate.mp4"]];
}
Hope that would have solved your problem :)
Related
I have created an app that incorporates a table view, detail view, and a web view. I have established a cell in the table view that takes a URL from an RSS feed and will display it in a webview. The URL is an .MP4 file which causes the video to play. The problem I am having is that when the video ends, I cannot go back to the previous screen. The code is below:
DetailViewController.m load webview
if (indexPath.section == SectionHeader && indexPath.row == SectionHeaderEnclosure) {
if (item.enclosures) {
for (NSDictionary *dict in item.enclosures){
NSString *url = [dict objectForKey:#"url"];
NSLog(#" url is : %#",url);
//EXPERIMENTAL
WebViewController *webVC = [[WebViewController alloc] initWithURL:url];
[self presentModalViewController:webVC animated:YES];
}
}
}
WebViewController.m
- (void)loadView
{
UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
self.view = webView;
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:_url]]];
}
//Dismiss modal view
- (IBAction) done:(id)sender {
NSLog(#"done:");
[self dismissModalViewControllerAnimated:YES];
}
I think it would be better to use an MPMoviePlayerViewController. The documentation shows how to set it up with the URL directly using initWithContentURL: and present it modally. You can listen for notifications thet the movie has ended and dismiss it when done. Lots of good stuff in the documentation.
I have successfully implemented embedded vimeo videos into my app, however i would like to create placeholder images as an overlay on the videos whilst they are not playing. Does anyone have an idea of how to do this?
#import "FifthDetailViewController.h"
#interface FifthDetailViewController (Private)
- (void)embedVimeoInWebView:(NSString *)urlString webView: (UIWebView *)aWebView;
#end
#implementation FifthDetailViewController
#synthesize toolbar;
#synthesize videoOne;
#pragma mark -
#pragma mark View lifecycle
- (void) viewDidLoad{
[super viewDidLoad];
[self embedVimeoInWebView:#"http://player.vimeo.com/video/19967404" webView:videoOne];
}
- (void)embedVimeoInWebView:(NSString *)urlString webView:(UIWebView *)aWebView {
NSString *embedHTML = #"\
<html><head>\
<style type=\"text/css\">\
body {\
background-color: transparent;\
color: white;\
}\
</style>\
</head><body style=\"margin:-2\">\
<iframe src=\"%#\" type=\"application/x-shockwave-flash\" \
width=\"%0.0f\" height=\"%0.0f\"></iframe>\
</body></html>";
NSString *html = [NSString stringWithFormat:embedHTML, urlString, aWebView.frame.size.width, aWebView.frame.size.height];
//UIWebView *aWebView = [[UIWebView alloc] initWithFrame:frame];
[aWebView loadHTMLString:html baseURL:nil];
//----Disable Scroll UIWebView----
[[[aWebView subviews] lastObject] setScrollEnabled:NO];
//[mainView addSubview:aWebView];
//[self.mainView addSubview:videoView];
[aWebView release];
}
- (void)dealloc {
[toolbar release];
[super dealloc];
}
#end
This is what i have so far.
The approach we took with youtube videos is as follow (I guess you can do something similar with vimeo).
What you need to do is set an imageview on top the webview, which should display the thumbnail img of your vimeo video (this is what I understand from your question).
You can retrieve thumbnail images with Vimeo API
To get data about a specific video, use the following url:
http://vimeo.com/api/v2/video/video_id.output
video_id The ID of the video you want information for.
output Specify the output type. We currently offer JSON, PHP, and XML formats.
You'll get three thumbnails, one for different size (small, medium, large).
Since your imageView will hide the webview and the button on it to start playing, you will need to perform an action when you tap the uimageview (or just set an uibutton on top). Then, the selector should call something like this:
**
* When webview has loaded, send an action to itself so it starts the video
* playback automatically
*/
- (void)webViewDidFinishLoad:(UIWebView *)_webView {
_webView.hidden = NO;
UIButton *b = [self findButtonInView:_webView];
[b sendActionsForControlEvents:UIControlEventTouchUpInside];
}
- (IBAction) playVideo:(id)sender {
NSString *key = [NSString stringWithFormat:#"%d", [sender tag]];
UIWebView *youtubeView =
[[UIWebView alloc] initWithFrame:CGRectMake(-180, 100, 160, 80)];
youtubeView.tag = 3000;
youtubeView.hidden = YES;
[self.tableView addSubview:youtubeView];
[self embedYouTubeIntoWebview:youtubeView withURL:[[self.nodeCollection objectForKey:
key] valueForKey:#"videoURL"]
inFrame:youtubeView.frame];
[youtubeView release];
}
I've been trying and researching for countless hours but for some reason I just cant get my head around it and I know its a simple answer. Please Help!
I have a view with different buttons, -(ScrollViewController1)
the different buttons push in one view, -(b1ViewController)
this view contains the media player,
In a nutshell, I cant figure out how to get the media player to play a different audio file depending on which button in the first view was pressed.
I'm trying not to make a different view with a different media player for every button.
Could someone demonstrate it please so that I can understand it? Thanks a million.
Heres the relevant code-
(ps- theres a reason for the tags, I didnt want to get too much into for the sake of asking a clear question and keeping it straight forward.)
#implementation ScrollViewController1
- (IBAction)pressedb1view {
if (thebutton.tag==101) {
[self performSelector:#selector(dismissb1pop:) withObject:nil afterDelay:0.1];
b1view.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:b1view animated:YES];
}
if (thebutton.tag==102) {
[self performSelector:#selector(dismissb1pop:) withObject:nil afterDelay:0.1];
b1view.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:b1view animated:YES];
}
if (thebutton.tag==103) {
[self performSelector:#selector(dismissb1pop:) withObject:nil afterDelay:0.1];
b1view.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:b1view animated:YES];
}
}
etc, etc, etc....
in the next view which contains the mediaplayer I have-
#import <UIKit/UIKit.h>
#import <MediaPlayer/MediaPlayer.h>
#interface b1ViewController : UIViewController {
MPMoviePlayerController *moviePlayer;
NSURL *movieURL;
}
in the .m -
-(void)viewWillAppear:(BOOL)animated {
[[self navigationController] setNavigationBarHidden:NO animated:YES];
NSString *urlStr = [[NSBundle mainBundle] pathForResource:#"music1" ofType:#"mp3"];
NSURL *url = [NSURL fileURLWithPath:urlStr];
moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:movieURL];
[self.view addSubview:moviePlayer.view];
moviePlayer.view.frame = CGRectMake(0, 0, 320, 40);
[moviePlayer play];
}
EDIT:
Im passing text from the first view to a uilabel on the second view using the following in the first view-
[b1view changeSiteText:#"im stuck here"];
in the second view Im doing this in the .h-
- (IBAction) changeSiteText:(NSString *)str;
and in the .m im doing this-
- (IBAction) changeSiteText:(NSString *)str{
lblSiteTxt.text = str;
}
Is there a way to implement a similar method for the mediaplayer,??? maybe doing
something like
NSString *urlStr = [[NSBundle mainBundle] pathForResource:#"%#" ofType:#"mp3", str];
Im stuck!!
Help!
Do you push the view or present it?
Add a method in the player class which when passed various arguments it plays the appropriate track or whatever. Then the different IBActions will invoke this method.
Every time I load a new page with UIWebView the before loaded page is shown for a short time.
How can I clear that cache? Another possibility would be to dealloc UIWebview. I tried that but than my UIWebView is always "empty". How should the alloc and dealloc be done in this case?
I noticed that the UIWebView is consuming about 10 MB RAM. Now the UIWebView is loaded together with the ViewController. And the view is autoreleased as well as the UIWebView is autoreleased. Wouldn't it be better to dealloc the WebView each time?
Solution:
- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
CGRect frame = CGRectMake(0, 0, 320, 480);
self.webView = [[[UIWebView alloc]initWithFrame:frame] autorelease];
self.webView.scalesPageToFit = YES;
[self.view addSubview:self.webView];
}
- (void) viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
[self.webView removeFromSuperview];
self.webView = nil;
}
I had nearly the same problem. I wanted the webview cache to be cleared, because everytime i reload a local webpage in an UIWebView, the old one is shown. So I found a solution by simply setting the cachePolicy property of the request. Use a NSMutableURLRequest to set this property. With all that everything works fine with reloading the UIWebView.
NSURL *url = [NSURL fileURLWithPath:MyHTMLFilePath];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
[self.webView loadRequest:request];
Hope that helps!
My solution to this problem was to create the UIWebView programmatically on viewWillAppear: and to release it on viewDidDisappear:, like this:
- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.webView = [[[UIWebView alloc]initWithFrame:exampleFrame] autorelease];
self.webView.scalesPageToFit = YES;
self.webView.delegate = self;
self.webView.autoresizingMask = webViewBed.autoresizingMask;
[exampleView addSubview:self.webView];
}
- (void) viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
[self.webView removeFromSuperview];
self.webView.delegate = nil;
self.webView = nil;
}
If you do this and your UIWebView doesn't get released you should check it's retain count and understand who is retaining it.
If you want to remove all cached responses, you may also want to try something like this:
[[NSURLCache sharedURLCache] removeAllCachedResponses];
If I had to make a guess your property for webView is
#property (nonatomic, retain) IBOutlet UIWebView *webView;
Correct? The important part is the retain.
self.webView = [[UIWebView alloc]initWithFrame:frame];
The above code allocates a UIWebView (meaning retainCount = 1) and then adds it to self.webView, where it is retained again (retainCount = 2).
Change the code to the following, and your webView should be deallocated.
self.webView = [[[UIWebView alloc]initWithFrame:frame] autorelease];
addSubview: can only be called on UIViews.
//[self.navigationController addSubview:self.webView];
should be
[self.navigationController.view addSubview:self.webView];
I did something simpler, I just set the webView's alpha to 0 on loadRequest and 1 on webViewDidFinishLoad.
thewebview.alpha=0.0;
thewebview.backgroundColor=[UIColor whiteColor];
[thewebview loadRequest:[NSURLRequest requestWithURL:url(str)]];
and
- (void)webViewDidFinishLoad:(UIWebView *)webView {
thewebview.alpha=1.0;
}
(Actually I have a fade-in, as rendering f.ex. a PDF can take 1/5 seconds or so.)
You could also load #"about:blank" after the webview disappears, then it will be empty the next time you access it.
Suppose user taps on a button and video begins to play. Now when video plays, it always in full screen mode.
Video should be played in a portrait mode (but normally video is played in landscape mode). How can I do this?
Just an update, the latest iPhone SDK 3.2+ will now allow the programmers to show the video in any desired size and Orientation, New MPMoviePlayerView is provided, which is a property of MPMoviePlayerController, this view will have the video, which you can add as a subview to your view.
#interface MPMoviePlayerController (extend)
-(void)setOrientation:(int)orientation animated:(BOOL)value;
#end
moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:movieUR];
[moviePlayer setOrientation:UIDeviceOrientationPortrait animated:NO];
if (moviePlayer)
{
[self.moviePlayer play];
}
This Solution will be rejected by Apple, as setOrientation for movie player is the Private API. You need to be careful, but it may work on Jailbroke iPhones.
From the documented docs i do not think this is possible using the built in media player
Try this out.
I found something new.
#interface MPMoviePlayerController (extend)
-(void)setOrientation:(int)orientation animated:(BOOL)value;
#end
moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:movieUR];
[moviePlayer setOrientation:UIDeviceOrientationPortrait animated:NO];
if (moviePlayer)
{
[self.moviePlayer play];
}
Here's what I did. Add NSNotification to notify you when preloading of the video finishes.
- (void)playVideoUrl:(NSString *)videoUrl {
NSURL *url = [NSURL URLWithString:videoUrl];
MPMoviePlayerController* theMovie=[[MPMoviePlayerController alloc]
initWithContentURL:url];
[[NSNotificationCenter defaultCenter] addObserver:self
//MPMoviePlayerContentPreloadDidFinishNotification
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(myMovieFinishedPreloading:)
name:MPMoviePlayerContentPreloadDidFinishNotification
object:theMovie];
// Movie playback is asynchronous, so this method returns immediately.
[theMovie play];
}
Callback selector:
-(void)myMovieFinishedPreloading:(NSNotification*)aNotification {
NSArray *windows = [[UIApplication sharedApplication] windows];
UIWindow *moviePlayerWindow = nil;
if ([windows count] > 1)
{
moviePlayerWindow = [[UIApplication sharedApplication] keyWindow];
}
CGAffineTransform transform = CGAffineTransformMakeScale(0.5, 0.5);
transform = CGAffineTransformRotate(transform, -90.0f*M_PI/180.0f);
[moviePlayerWindow setTransform:transform];
}