MJPEG in UIWebView - How to change scale with javascript (iphone) - iphone

I'm displaying an MJPEG stream in a UIWebView. I have two different sizes I want to use for the UIWebView. The video size is constant.
So setScalesPageToFit isn't flexible enough, and I have no control over the source to change the viewport meta tag. So I'm left thinking that I need to do this via javascript (of which I have very little knowledge). However I'm stuck with two issues:
1) What javascript to call to change the scale/width of the uiwebview. I've tried variations on:
[webView stringByEvaluatingJavaScriptFromString:#"document.getElementsByTagName('body')[0].style.width='320px'"];
[webView stringByEvaluatingJavaScriptFromString:#"document.getElementsByTagName('body')[0].style.webkitTransform='scale(1.0)'"];
2) I can't stringByEvaluatingJavaScriptFromString from webViewDidFinishLoad, since this doesn't get called when streaming. So I'm calling it straight after my loadRequest.
[edit] I've also now tried calling this a couple seconds later via NSTimer (although i can't really use this approach since I don't know when the video feed arrives). Anyway I see some impact on the scale, but the next frame that arrives seems to reset the scale.

I've recently revisited this and now use a transform on the containing view

Related

How Can I Record the Screen with Acceptable Performance While Keeping the UI Responsive?

I'm looking for help with a performance issue in an Objective-C based iOS app.
I have an iOS application that captures the screen's contents using CALayer's renderInContext method. It attempts to capture enough screen frames to create a video using AVFoundation. The screen recording is then combined with other elements for research purposes on usability. While the screen is being captured, the app may also be displaying the contents of a UIWebView, going out over the network to fetch data, etc... The content of the Web view is not under my control - it is arbitrary content from the Web.
This setup is working but as you might imagine, it's not buttery smooth. Since the layer must be rendered on the main thread, there's more UI contention than I'd like. What I'd like to do is to have a setup where the responsiveness of the UI is prioritized over the screen capture. For instance, if the user is scrolling the Web view, I'd rather drop frames on the recording than have a terrible scrolling experience.
I've experimented with several techniques, from dispatch_source coalescing to submitting the frame capture requests as blocks to the main queue to CADisplayLink. So far they all seem to perform about the same. The frame capture is currently being triggered in the drawRect of the screen's main view.
What I'm asking here is: given the above, what techniques would you suggest I try to achieve my goals? I realize the answer may be that there is no great answer... but I'd like to try anything, however wacky it might sound.
NOTE: Whatever techniques need to be App Store friendly. Can't use something like the CoreSurface hack that Display Recorder used/uses.
Thanks for your help!
"Since the layer must be rendered on the main thread" this is not true, as long as you don't touch UIKit.
Please see https://stackoverflow.com/a/12844171/136305
Maybe you can record at half resolution to speed up things, if that fits the requirements?

UIImageView Animation delay between frames?

I am trying to create an animation using a UIImageView with an array if images. It works great, except that I need a different delay between some of the frames. In an animated gif you can set the delay between frames. Every example I see of an animated UIImageView has a fixed delay between images.
Does anyone know how I can set a different delay between frames? Or, is there an example of such?
Maybe UIImageView is not the right thing to use, so if anyone has an alternative please let me know.
I have posted a similiar question in other forums and no one seems to be able to answer this. It seems like it should bo doable, since .gif images have had this forever.
Thanks
It may seem hacky, but:
From UIImageView documentation:
animationImages
An array of UIImage objects to use for an animation.
#property(nonatomic, copy) NSArray *animationImages
Discussion
The array must contain UIImage objects. You may use the same
image object more than once in the array. Setting this property to
a value other than nil hides the image represented by the image
property. The value of this property is nil by default.
So you need to add your UIImage several times to the array for a delay.
UIImageView does not support a different delay between different images. You will have to use multiple UIImageViews and manage the transition between them manually if you want to have different delays between frames.
Another approach would be to use a UIWebView which is sized exactly to fit a .gif image that has the delay settings you want.
You have to use different UIImageView to get this working. Try this application page. Might be helpful for you. Link: http://www.raywenderlich.com/2454/how-to-use-uiview-animation-tutorial
If you would like to try my animation library in your iOS app, it offers a complete solution to this problem. For example, you could take a look at the APNG app, it is a free app in the iTunes store that displays animated APNG files. This app was created using my AVAnimator library which contains APNG and GIF decoding support. The APNG format works just like a GIF in the sense that each frame can have a delay time, you would use existing software to create the APNG in this case. But, it is easier to just encode a new .mvid file (this is a custom video file format) from a series of PNG imags. To create a longer delay, you simply repeat frames that do not change in the input PNG image series. Either approach could be used to create an input movie that could display with a variable amount of time in between specific frames (the overall FPS would be the same, but specific frames can simply repeat so that they do not change for say N frames in a row). You can also implement specific user interactions like starting an animation, pausing on a specific frame, and then starting again from that same frame.

What is the best way to view large PDFs on iOS?

I am currently using QLPreviewController to view PDFs (250MB+) However it cannot deal with real large files. Either I get the info that not the whole file has been loaded or the whole app just dies.
I also need to customize the view which is nit possible using QLPreviewController.
What should I do? Use UIWebView instead? Or will I have to use CGContextDrawPDFPage?
Using the latter, how will I get zooming implemented?
I would go with your suggestion of using a UIWebView. Doing so will automatically give you zoom support and the UIWebView should handle loading extremely large PDF's.
If you have decided to go with Quartz, this link looks very promising for zoom support.

How to get WebView Content Size

I am looking to find WebView content size to scale data to fit into small size of WebView Frame.
WebView is continuous loading data as getting images from IP Camera so -(void)webViewDidFinishLoad delegate method is not called, otherwise [webview sizeThatFits:CGSizeZero] would give receiver content size.
How to get WebView content size which is continuous loading data ?
Thanks,
See my answer to a similar question. Instead of -webViewDidFinishLoad you should consider calling this using a timer (and checking whether something has been loaded, first).
If the HTML is under your control, you might wanna call it using a JavaScipt onLoad handler that tries to fetch a custom URL that you can intercept in -webView:shouldStartLoadWithRequest:navigationType:.

Is there a HTML wrapper in Cocoa other then UIWebView?

I have a bunch of texts and images (taken from the content tag of a RSS feed item) that I want to display in my app. I've managed to extract them from the entire content tag with some regular expressions. But the thing is, in order for the texts to appear before all the images are loaded, I need to preload all the images, and even more, I need to reposition all the texts/images when an image is loaded, because I don't know their size at first, to position the element under them correctly.
I realized this is too much hard-work for such a simple task.
I searched for some simple HTML wrapper but I found nothing. And than I realized: hey, I can insert HTML directly into an UIWebView. But then again, I see UIWebView more like an iFrame in HTML, and by that I mean not a very flexible/fluid element. The content will be bigger than the iPhone screen height, can the UIWebView adjust to fit it's contents? I don't want the browser zoom features and all, but rather to blend in the page.
So bottom line: In order to display a bunch of texts combined with images, should I continue with my initial pain-in-the-ass method, should I use a UIWebView, or is there another simple element like the one in my dreams? :)
Thanks.
Definitely use the web view; it has hundreds of person-years of work behind it, and is realistically impossible for you to reproduce by yourself. To keep it from zooming, you can add a viewport meta tag to your HTML fragment.
...[S]hould I continue with my initial pain-in-the-ass method, should I use a UIWebView, or is there another simple element like the one in my dreams...
I'm not entirely sure what you have against UIWebView, it's a decent and fairly complex element that can support many behaviors. One of the extremely attractive properties of IB and Cocoa development is that prototyping is very quick. I think you should spend half an hour and play around with the component. Writing your own code is definitely an option, but layout engines (ie WebKit in UIWebView/Safari, or Gecko in Firefox) is a complicated task. Why reinvent the wheel?
HTH.