NSURLConnection downloading poor quality JPEGs on 3G - cocoa-touch

I am downloading a JPEG image from a server and assigning it to an image object in my iPhone app using an NSURLConnection.
All works fine when I'm on a Wifi connection, but as soon as I switch to 3G, the quality of the JPEG downloaded reduces dramatically.
Has anyone else experienced this?
Does anyone know of a way to force the iPhone to download the full quality JPEG?
Thanks in advance!
Nick.

If it's the 3G provider that compresses data on the fly I don't think you can do anything about it. Download the image with Safari via 3G -> if the image looks bad (and I expect it will) then it's the provider that compresses it.
To workaround this problem zip the image on the server and unzip it in the application -> this should bypass the compression on the 3G side.

A simple trick is to use https instead of http - this appears to work on O2.

I know this question is quite old but incase this is of any use to anyone...
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:theURL];
// Add headers to avoid mobile network operator image compression
[request setValue:#"no-cache" forHTTPHeaderField:#"Pragma"];
[request setValue:#"no-cache" forHTTPHeaderField:#"Cache-Control"];
Should stop the compression of images.
The mobile operator compresses images in order to save bandwidth, but they tend to respect these header fields, and allow you to request the uncompressed image.

Related

Play encrypted video with AVPlayer

I'm implementing an application that contains video player. For some reasons video files are encrypted with AES, and size of these files can be rather big to avoid loading it to RAM as one piece. I'm looking for some way to play it with AVPlayer.
Tried:
1) Custom NSURLProtocol as suggested here http://aptogo.co.uk/2010/07/protecting-resources/
Didn't work, I suggest that AVPlayer uses it's own and mine does not get called.
2) Use AVAsset to chop video in small chunks and then feed them to AVPlayer - failed because there's no API in AVPlayer for that.
Any workaround would be greatly appreciated :)
You have 2 options:
If targeting iOS 7 and newer the check out AVAssetResourceLoaderDelegate. It allows you to do what you would with a custom NSURLProtocol but specifically for AVPlayer.
Emulate an HTTP server with support for the Range header and point the AVURLAsset to localhost.
I implemented #2 before and can provide more info if needed.
I just downloaded the Apple sample project https://developer.apple.com/library/ios/samplecode/sc1791/Listings/ReadMe_txt.html and it seems to do exactly what you want.
The delegate catch each AVURLAsset's AVAssetResourceLoader calls and makes up a brand new .m3a8 file with a custom decryption key in it.
Then it feeds the player with all .ts file URLs in the m3a8.
The project is a good overview of what it is possible to do with HLS feeds.

Best way to write to file a large HTTP response

I'm looking for ways of writing to file the results of a web request. In languages based on the JVM or the CLR there are appropriate Stream-based techniques I'm familiar with, however I'm clueless on how could that be done in Objective-C.
What I need is essentially a way to send an HTTP request (with a custom header set) and write the HTTP response content as I receive it (due to memory constraints I can't afford to get the whole file or even a large portion of it before persisting the contents).
Ideas/suggestions/snippets?
Thanks in advance!
P.S.: I'm developing for Mac OS and I'm already using ASIHTTPRequest, if that can be of help.
Edit: I should specify that I don't want to write all of the contents returned by the server to disk unless I can write them directly at a certain offset of a file (which I'll then be able to manipulate), so anything that dumps straight to a new file or to the beginning of a file won't work for me.
There a few ways of doing it, depends on how you want to handle the responds
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDownloadDestinationPath:#"/Users/Test/Desktop/cool.html"];
with setDownloadDestinationPath: set, it'll save into temporary path, and when it finished, it'll move it to your downloadDestinationPath you set.
Or you can implement request:didReceiveData: delegate (see ASIHTTPRequestDelegate.h), and handle it yourself. This is similar to stream.
PS. I only ever use ASIHTTPRequest on iOS, not Mac OS, so I'm not entirely sure if it will work for you.

iPad: Captured video w/ AVCam Sample, but it is 1080x720, how do you compress it?

Captured video with AVCam Sample Project, but it is huge at 1080x720 resolution. How can I compress for saving to a web server?
I modified the sample code to not save the video file to the AssetsLibrary in "AvCamCaptureManager.m" "recordingDidFinishToOutputFileURL", so I take that outputfile url and send it to my webserver using ASIHttp. These video files are huge, I want to reduce their resolution to 568x320 to reduce the file size.
Given the uncompressed url, how do I compress it to a smaller file format and/or resolution?
I just saw your question, if it's still of any help, try reducing the quelity for the whole session
session.sessionPreset = AVCaptureSessionPresetMedium;
or
session.sessionPreset = AVCaptureSessionPresetLow;
The first will give smaller files while keeping a decent quality, and the latter will give a very small file with the lowest quality available for your device.

Download an save an image file on HDD with Cocoa

I'm building a program, and I'm quite confident using Objective-C, but I don't know how to programmatically download a file from the web and copy it on the hard drive.
I started with :
NSString url = #"http://spiritofpolo.com/images/logo.png";
NSData* data = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]];
But then I don't know what to do with the data... that sucks, no ;)
Can somebody help?
You're close; the last thing you need is a call to -[NSData writeToFile:atomically:].
While that approach, with the final step provided by fbrereto, will work, it does not handle failure gracefully (indeed, it does not handle any sort of failure at all) and will block your application for the duration of the download.
Use NSURLDownload instead. It requires more code, but broken network connections, cut-off downloads, and inaccessible destination paths will not (necessarily) silently break your app.

How do I record video to a local disk in AIR?

I'm trying to record a webcam's video and audio to a FLV file stored on the users local hard disk. I have a version of this code working which uses NetConnection and NetStream to stream the video over a network to a FMS (Red5) server, but I'd like to be able to store the video locally for low bandwidth/flaky network situations. I'm using FLex 3.2 and AIR 1.5, so I don't believe there should be any sandbox restrictions which prevent this from occurring.
Things I've seen:
FileStream - Allows reading.writing local files but no .attachCamera and .attachAudio methids for creating a FLV.
flvrecorder - Produces screen grabs from the web cam and creates it's own flv file. Doesn't support Audio. License prohibits commercial use.
SimpleFLVWriter.as - Similar to flvrecorder without the wierd license. Doesn't support audio.
This stackoverflow post - Which demonstrates the playback of a video from local disk using a NetConnection/NetStream.
Given that I have a version already which uses NetStream to stream to the server I thought the last was most promising and went ahead and put together this demo application. The code compiles and runs without errors, but I don't have a FLV file on disk which the stop button is clicked.
-
<mx:Script>
<![CDATA[
private var _diskStream:NetStream;
private var _diskConn:NetConnection;
private var _camera:Camera;
private var _mic:Microphone;
public function cmdStart_Click():void {
_camera = Camera.getCamera();
_camera.setQuality(144000, 85);
_camera.setMode(320, 240, 15);
_camera.setKeyFrameInterval(60);
_mic = Microphone.getMicrophone();
videoDisplay.attachCamera(_camera);
_diskConn = new NetConnection();
_diskConn.connect(null);
_diskStream = new NetStream(_diskConn);
_diskStream.client = this;
_diskStream.attachCamera(_camera);
_diskStream.attachAudio(_mic);
_diskStream.publish("file://c:/test.flv", "record");
}
public function cmdStop_Click() {
_diskStream.close();
videoDisplay.close();
}
]]>
</mx:Script>
<mx:VideoDisplay x="10" y="10" width="320" height="240" id="videoDisplay" />
<mx:Button x="10" y="258" label="Start" click="cmdStart_Click()" id="cmdStart"/>
<mx:Button x="73" y="258" label="Stop" id="cmdStop" click="cmdStop_Click()"/>
</mx:WindowedApplication>
It seems to me that there's either something wrong with the above code which is preventing it from working, or NetStream just can't be abused in this wany to record video.
What I'd like to know is, a) What (if anything) is wrong with the code above? b) If NetStream doesn't support recording to disk, are there any other alternatives which capture Audio AND Video to a file on the users local hard disk?
Thanks in advance!
It is not possible To stream video directly to the local disk without using some streaming service like Windows Media encoder, or Red5 or Adobe's media server or something else.
I have tried all the samples on the internet with no solution to date.
look at this link for another possibility:
http://www.zeropointnine.com/blog/updated-flv-encoder-alchem/
My solution was to embed Red5 into AIR.
Sharing with you my article
http://mydevrecords.blogspot.com/2012/01/local-recording-in-adobe-air-using-red5.html
In general, the solution is to embed free media server Red5 into AIR like an asset. So, the server will be present in AIR application folder. Then, through the NativeProcess, you can run Red5 and have its instance in memory. As result, you can have local video recording without any network issues.
I am also trying to do the same thing, but I have been told from the developers of avchat.net that it is not possible to do this with AIR at the moment. If you do find out how to do it, I would love to know!
I also found this link, not sure how helpful it is http://www.zeropointnine.com/blog/webcam-dvr-for-apollo/
Well, I just think that letting it connect to nothing(NULL) doesn't work. I've already let him try to connect to localhost, but that didn't work out either. I don't think this is even possible. Streaming video works only with Flash Media Server and Red5, not local. Maybe you could install Red5 on you PC?
Sadly video support in flash from cameras is very poor. When you stream its raw so the issue is that you have to encode to FLV and doing it in real time takes a very fast computer. First gen concepts would write raw bitmaps to a file (or serialize an array) then a second method would convert the file to an FLV. Basically you have to poll the camera and save each frame as a bitmap then stack in an array. This is very limited and could not do audio. It was also very hard to get above 5-10fps.
The gent at zero point nine, came up with a new version and your on the right path. Look at the new flv recorder. I spent a lot of time working with this but never quite got it to work for my needs (two cameras). I just could not get the FPS i needed. But it might work for you. It was much faster than the original method.
The only other working option I know of is to have the Red5 save the video and download it back to the app.