XCDYouTubeVideoPlayer opens and close - ios

I've start working with XCDYouTubeVideoPlayer. It does seem to have, some small issues. When I use the method (like below) to call the player it opens it and close it right away.
I've imported following frameworks:
mediaplayer
AVfoundation
and added the `XCDYouTubeVideoPlayerViewController.h and .m
In the viewController.m I've added this method:
- (IBAction) play:(id)sender
{
[self.view endEditing:YES];
NSString *link = #"m01MYOpbdIk";
XCDYouTubeVideoPlayerViewController *videoPlayerViewController = [[XCDYouTubeVideoPlayerViewController alloc] initWithVideoIdentifier:link];
[self presentMoviePlayerViewControllerAnimated:videoPlayerViewController];
}
At the moment its opening and closing the XCDYouTubeVideoPlayer right a way. What am i doing wrong?

I not understand why, but for me , in iOS8 the line
XCDYouTubeVideoPlayerViewController.m at #79
was calling the method :
- (id) initWithContentURL:(NSURL *)contentURL
{
#throw [NSException exceptionWithName:NSGenericException reason:#"Use the
` initWithVideoIdentifier:` method instead." userInfo:nil];
}
I just comment it and works!

XCDYouTubeVideoPlayer library build the youtube "streaming link", by appending the url with the signature provided. It seems that the "url" now has the signature along with it and the "sig" key comes null, which thereby negates the if statement in the function
(NSURL *) videoURLWithData:(NSData *)data error:(NSError * __autoreleasing *)error
Goto file
XCDYouTubeVideoPlayerViewController.m at #248
you will see a for-loop
for (NSString *streamQuery in streamQueries)
{
NSDictionary *stream = DictionaryWithQueryString(streamQuery, queryEncoding);
NSString *type = stream[#"type"];
NSString *urlString = stream[#"url"];
NSString *signature = stream[#"sig"];
if (urlString && signature && [AVURLAsset isPlayableExtendedMIMEType:type])
{
NSURL *streamURL = [NSURL URLWithString:[NSString
stringWithFormat:#"%#&signature=%#",
urlString,
signature]];
streamURLs[#([stream[#"itag"] integerValue])] = streamURL;
}
change it to this (remove the signature variable from if statement and modify the URLWithString)
for (NSString *streamQuery in streamQueries)
{
NSDictionary *stream = DictionaryWithQueryString(streamQuery, queryEncoding);
NSString *type = stream[#"type"];
NSString *urlString = stream[#"url"];
if (urlString && [AVURLAsset isPlayableExtendedMIMEType:type])
{
NSURL *streamURL = [NSURL URLWithString:urlString];
streamURLs[#([stream[#"itag"] integerValue])] = streamURL;
}

Related

Problems loading UIWebView

I'm attempting to write a SplitView control program in which pressing a table cell in the masterViewController causes an associated web page to load in the detail view controller. I have the following method in the detail view controller that I can confirm is getting called and is receiving the correct input:
-(void)masterAction:(id)sender {
NSString *http = #"http://";
http = [http stringByAppendingString:sender];
_urlString = http;
NSURL *url= [NSURL URLWithString:_urlString];
[self.web loadRequest:[NSURLRequest requestWithURL:url]];
}
However, nothing is loading. Any ideas why this might be? The only way I've been able to get anything at all to load is to insert something similar to the following in my viewDidLoad method:
NSURL *url= [NSURL URLWithString:#"http://www.google.com];
[self.web loadRequest:[NSURLRequest requestWithURL:url]];
The method is being called using:
-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *thread = [self.issueData objectForKey:#"responseData"];
NSDictionary *feed = [thread objectForKey:#"feed"];
NSArray *entries = [feed objectForKey:#"entries"];
NSDictionary *posts = entries[indexPath.row];
NSString *urlString = [posts objectForKey:#"link"];
NSArray *split = [urlString componentsSeparatedByString:#"url=http://"];
NSString *url = [split objectAtIndex:1];
[self.delegate masterAction:url];
}
set the delegate of webview.
and try this.
NSString *myUrl = #"http://www.YourWebSite.com";
NSURL *webUrl = [NSURL URLWithString:myUrl];
[webObj loadRequest:[NSURLRequest requestWithURL:webUrl]];
I duplicated this code in a test project and the only piece of code where something can go wrong is if you are forgetting to put www. after the http:// before the domain name.
Trying changing your masterAction method to the one below:
- (void) masterAction: (id) sender
{
if (![sender isKindOfClass:[NSString class]]) return;
NSString *http = #"http://www.";
NSString *urlString = [http stringByAppendingString:sender];
NSURL *url = [NSURL URLWithString:urlString];
[self.web loadRequest:[NSURLRequest requestWithURL:url]];
}
If this is not the issue and the string being sent to the method contains the www. try setting the delegate of the UIWebView to see if any error is thrown when loading the request.

Could not be able to play single video in web view

In my application i need to play single video in UIWebView i could be able to play playlist in UIWebView.
link to get video is:
http://www.youtube.com/watch?v=5cCjaqi31XE&feature=youtube_gdata
here is my code:
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *videoURL=[self getYTUrlStr:stringURL];
NSURL *url=[NSURL URLWithString:videoURL];
[self.web loadRequest:[NSURLRequest requestWithURL:url]];
NSString *videoURL=[self getYTUrlStr:stringURL];
- (NSString*)getYTUrlStr:(NSString*)url
{
if (url == nil)
return nil;
NSString *retVal = [url stringByReplacingOccurrencesOfString:#"watch?v=" withString:#"v/"];
NSRange pos=[retVal rangeOfString:#"version"];
if(pos.location == NSNotFound)
{
retVal = [retVal stringByAppendingString:#"?version=3&hl=en_EN"];
}
return retVal;
}
Need to modify link as below
videoURL = [videoURL stringByReplacingOccurrencesOfString:#"http://www.youtube.com/v/" withString:#"http://www.youtube.com/embed/"];
videoURL=[videoURL stringByReplacingOccurrencesOfString:#"?version=3&hl=en_EN" withString:#"?feature=player_detailpag"];
videoURL = [videoURL stringByReplacingOccurrencesOfString:#"?version=3&f=user_uploads&app=youtube_gdata" withString:#"?feature=player_detailpage"];
Then provided to instance method to UIWebView instance method loadRequest as NSURLRequest.

How does one have buttons to do different things from the same view?

I have three buttons made with interface builder in the same view of my app. I want each button to do separate IBActions, but when I try to do
- (IBAction)button:(id)sender {
if([[Reachability reachabilityForInternetConnection] currentReachabilityStatus] == NotReachable) {
[self.textfield resignFirstResponder];
self.translation.text = #"Sorry, you need an internet connection to translate.";
}
else {
// Connected to the internet
[self.textfield resignFirstResponder];
NSString *toTranslate = self.textfield.text;
NSString *url = [NSString stringWithFormat:#"http://www.archives.nd.edu/cgi-bin/wordz.pl?keyword=%#", toTranslate];
NSURL *translationUrl = [NSURL URLWithString:url];
NSData *translationHtmlData = [NSData dataWithContentsOfURL:translationUrl];
TFHpple *translationParser = [TFHpple hppleWithHTMLData:translationHtmlData];
NSString *translationXpathQueryString = #"/html/body/pre";
NSArray *translationOutput = [translationParser searchWithXPathQuery:translationXpathQueryString];
NSString *translatedString = ((TFHppleElement *)translationOutput[0]).firstChild.content;
self.translation.text = translatedString;
}
}
it gives a "method definition for 'button' not found" warning on the #implementation of the viewcontroller.m.
What am I doing wrong with this method or is there a better method?
I think its an interface builder issue, try re-connecting the method from IB

Using AVURLAsset on a custom NSURLProtocol

I have written a custom NSURLProtocol (called "memory:") that allows me to fetch stored NSData items from a NSDictionary based on a name. For example, this code registers the NSURLProtocol class and adds some data:
[VPMemoryURLProtocol register];
[VPMemoryURLProtocol addData:data withName:#"video"];
This allows me to refer to the NSData via a url like "memory://video".
Below is my custom NSURLProtocol implementation:
NSMutableDictionary* gMemoryMap = nil;
#implementation VPMemoryURLProtocol
{
}
+ (void)register
{
static BOOL inited = NO;
if (!inited)
{
[NSURLProtocol registerClass:[VPMemoryURLProtocol class]];
inited = YES;
}
}
+ (void)addData:(NSData *)data withName:(NSString *)name
{
if (!gMemoryMap)
{
gMemoryMap = [NSMutableDictionary new];
}
gMemoryMap[name] = data;
}
+ (BOOL)canInitWithRequest:(NSURLRequest *)request
{
NSLog(#"URL: %#, Scheme: %#",
[[request URL] absoluteString],
[[request URL] scheme]);
NSString* theScheme = [[request URL] scheme];
return [theScheme caseInsensitiveCompare:#"memory"] == NSOrderedSame;
}
+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request
{
return request;
}
- (void)startLoading
{
NSString* name = [[self.request URL] path];
NSData* data = gMemoryMap[name];
NSURLResponse* response = [[NSURLResponse alloc] initWithURL:[self.request URL]
MIMEType:#"video/mp4"
expectedContentLength:-1
textEncodingName:nil];
id<NSURLProtocolClient> client = [self client];
[client URLProtocol:self didReceiveResponse:response
cacheStoragePolicy:NSURLCacheStorageNotAllowed];
[client URLProtocol:self didLoadData:data];
[client URLProtocolDidFinishLoading:self];
}
- (void)stopLoading
{
}
I am not sure whether this code works or not but that is not what I have a problem with. Despite registering the custom protocol, canInitWithRequest: is never called when I try to use the URL in this code:
NSURL* url = [NSURL URLWithString:#"memory://video"];
AVURLAsset* asset = [[AVURLAsset alloc] initWithURL:url options:nil];
AVAssetImageGenerator* imageGen = [AVAssetImageGenerator assetImageGeneratorWithAsset:asset];
CMTime time = CMTimeMakeWithSeconds(0, 600);
NSError* error;
CMTime actualTime;
CGImageRef image = [imageGen copyCGImageAtTime:time
actualTime:&actualTime
error:&error];
UIImage* uiImage = [UIImage imageWithCGImage:image];
CGImageRelease(image);
image is always nil if I use "memory://video" but works fine if I use "file:///...". What am I missing? Why isn't canInitWithRequest not being called? Does AVFoundation only support specific URL protocols and not custom ones?
Thanks
Certainly the underpinnings used to only support particular URL schemes— as an eBook developer I've seen this happen for any media type loaded through a URL such as epub:// or zip://. In those cases, on iOS 5.x and earlier, tracing through the relevant code would wind up in a QuickTime method which compared the URL scheme against a small number of supported ones: file, http, https, ftp and whatever it is that iTunes uses-- I forget what it's called.
In iOS 6+ there is a new API in AVFoundation, however, which is designed to help here. While I've not used it personally, this is how it should work:
NSURL* url = [NSURL URLWithString:#"memory://video"];
AVURLAsset* asset = [[AVURLAsset alloc] initWithURL:url options:nil];
////////////////////////////////////////////////////////////////
// NEW CODE START
AVAssetResourceLoader* loader = [asset resourceLoader];
id<AVAssetResourceLoaderDelegate> delegate = [SomeClass newInstanceWithNSURLProtocolClass: [VPMemoryURLProtocol class]];
[loader setDelegate: delegate queue: some_dispatch_queue];
// NEW CODE END
////////////////////////////////////////////////////////////////
AVAssetImageGenerator* imageGen = [AVAssetImageGenerator assetImageGeneratorWithAsset:asset];
CMTime time = CMTimeMakeWithSeconds(0, 600);
With this in place, you need only implement the AVAssetResourceLoader protocol somewhere, which is very simple as it contains only one method. Since you already have an NSURLProtocol implementation, all your real work is done and you can simply hand off the real work to the Cocoa loading system or your protocol class directly.
Again, I'll point out that I've yet to actually make use of this, so the above is entirely theoretical.

Setting UIDelegate for UIWebView

I read somewhere to read javascript console messages using the
- (void)webView:(WebView *)webView addMessageToConsole:(NSDictionary *)message
delegate method from the UIDelegate. But how/where do I need to set the delegate of the WebView (not the UIWebView) to my custom delegate?
I know Apple doesn't allow this in the AppStore, but I just want to implement this for debugging purposes.
What I tried so far:
- (void)webView:(id)sender didClearWindowObject:(id)windowObject forFrame:(WebFrame*)frame
{
[webView setUIDelegate:[[MyCustomUIDelegate alloc] init]];
}
and
-(void) webView:(id)webView windowScriptObjectAvailable:(id)newWindowScriptObject
{
[webView setUIDelegate:[[MyCustomUIDelegate alloc] init]];
}
This post may help you:
How can my iPhone Objective-C code get notified of Javascript errors in a UIWebView?
You can hook UIWebView control to hidden WebKit framework and get all exceptions, executed functions and similar.
Another way is posted here: Inject javascript code into the response that invoke to a objecie-c function.
NSString* path = [[NSBundle mainBundle] pathForResource:#"script"
ofType:#"js"];
NSString* content = [NSString stringWithContentsOfFile:path
encoding:NSUTF8StringEncoding
error:NULL];
[sender stringByEvaluatingJavaScriptFromString:content];
for exapmle the javascript code may be like:
console = new Object();
console.log = function(log) {
var iframe = document.createElement("IFRAME");
iframe.setAttribute("src", "ios-log:#iOS#" + log);
document.documentElement.appendChild(iframe);
iframe.parentNode.removeChild(iframe);
iframe = null;
}
console.debug = console.log;
console.info = console.log;
console.warn = console.log;
console.error = console.log;
and the objective-c code like:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSString *requestString = [[[request URL] absoluteString] stringByReplacingPercentEscapesUsingEncoding: NSUTF8StringEncoding];
//NSLog(requestString);
NSLog(#"Request: %#", requestString);
if ([requestString hasPrefix:#"ios-log:"]) {
NSString* logString = [[requestString componentsSeparatedByString:#":#iOS#"] objectAtIndex:1];
NSLog(#"UIWebView console: %#", logString);
return NO;
}
return YES;
}

Resources