How to live stream videos from iPhone to server like Ustream or Qik? I know there's something called Http Live Streaming from Apple, but most resources I found only talks about streaming videos from server to iPhone.
Is Apple's Http Living Streaming something I should use? Or something else? Thanks.
Broadcasting a live stream from your iPhone camera is pretty much as simple as everything else you can do with your iPhone, which means it's pretty darn easy—no camera add-ons or extra microphones required. Read on to find out what you need to have and what you need to know to get started.
Videos can be uploaded to Livestream Events by clicking the Editor icon in the top right corner of any of your event pages. You can either drag and drop your video file or click Browse to find your video within your computer's hard drive. Give your video a caption, description, and some search tags.
There isn't a built-in way to do this, as far as I know. As you say, HTTP Live Streaming is for downloads to the iPhone.
The way I'm doing it is to implement an AVCaptureSession, which has a delegate with a callback that's run on every frame. That callback sends each frame over the network to the server, which has a custom setup to receive it.
Here's the flow: https://developer.apple.com/library/content/documentation/AudioVideo/Conceptual/AVFoundationPG/Articles/04_MediaCapture.html#//apple_ref/doc/uid/TP40010188-CH5-SW2
And here's some code:
// make input device NSError *deviceError; AVCaptureDevice *cameraDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; AVCaptureDeviceInput *inputDevice = [AVCaptureDeviceInput deviceInputWithDevice:cameraDevice error:&deviceError]; // make output device AVCaptureVideoDataOutput *outputDevice = [[AVCaptureVideoDataOutput alloc] init]; [outputDevice setSampleBufferDelegate:self queue:dispatch_get_main_queue()]; // initialize capture session AVCaptureSession *captureSession = [[[AVCaptureSession alloc] init] autorelease]; [captureSession addInput:inputDevice]; [captureSession addOutput:outputDevice]; // make preview layer and add so that camera's view is displayed on screen AVCaptureVideoPreviewLayer *previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:captureSession]; previewLayer.frame = view.bounds; [view.layer addSublayer:previewLayer]; // go! [captureSession startRunning];
Then the output device's delegate (here, self) has to implement the callback:
-(void) captureOutput:(AVCaptureOutput*)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection*)connection { CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer( sampleBuffer ); CGSize imageSize = CVImageBufferGetEncodedSize( imageBuffer ); // also in the 'mediaSpecific' dict of the sampleBuffer NSLog( @"frame captured at %.fx%.f", imageSize.width, imageSize.height ); }
Several people have asked how to do this without sending the frames to the server one by one. The answer is complex...
Basically, in the didOutputSampleBuffer
function above, you add the samples into an AVAssetWriter
. I actually had three asset writers active at a time -- past, present, and future -- managed on different threads.
The past writer is in the process of closing the movie file and uploading it. The current writer is receiving the sample buffers from the camera. The future writer is in the process of opening a new movie file and preparing it for data. Every 5 seconds, I set past=current; current=future
and restart the sequence.
This then uploads video in 5-second chunks to the server. You can stitch the videos together with ffmpeg
if you want, or transcode them into MPEG-2 transport streams for HTTP Live Streaming. The video data itself is H.264-encoded by the asset writer, so transcoding merely changes the file's header format.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With