2013-07-01 27 views
7

Ho un codice online che cattura il video dalla fotocamera dell'iPhone e quindi lo memorizza in un file video e funziona perfettamente. Ma il mio scopo non è salvarlo nella memoria, ma inviarlo a un sever. Ho scoperto che esiste un server multimediale gratuito denominato WOWZA che consente lo streaming e anche Apple ha (HSL) HTTP Live Streaming e che i server si aspettano che il video sia in formato h.264 per i video e in mp3 per l'audio. Leggendo alcuni dei documenti su HSL di Apple, sono venuto a sapere che fornisce un URL diverso nel file di playlist per ogni segmento del file multimediale che viene poi riprodotto nell'ordine corretto su un dispositivo attraverso il browser. Non sono sicuro di come ottenere piccoli segmenti del file registrato dalla fotocamera del telefono e anche come convertirlo nel formato richiesto. seguito è il codice per cattura video:Come inviare il video catturato dalla fotocamera dell'iPhone a un server per lo streaming live?

Attuazione File

#import "THCaptureViewController.h" 
#import <AVFoundation/AVFoundation.h> 
#import "THPlayerViewController.h" 

#define VIDEO_FILE @"test.mov" 

@interface THCaptureViewController() 
@property (nonatomic, strong) AVCaptureSession *captureSession; 
@property (nonatomic, strong) AVCaptureMovieFileOutput *captureOutput; 
@property (nonatomic, weak) AVCaptureDeviceInput *activeVideoInput; 
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *previewLayer; 
@end 

@implementation THCaptureViewController 

- (void)viewDidLoad 
{ 
[super viewDidLoad]; 

    #if TARGET_IPHONE_SIMULATOR 
    self.simulatorView.hidden = NO; 
     [self.view bringSubviewToFront:self.simulatorView]; 
    #else 
    self.simulatorView.hidden = YES; 
    [self.view sendSubviewToBack:self.simulatorView]; 
    #endif 

// Hide the toggle button if device has less than 2 cameras. Does 3GS support iOS 6? 
self.toggleCameraButton.hidden = [[AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo] count] < 2; 

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), 
    ^{ 
    [self setUpCaptureSession]; 
}); 
} 

#pragma mark - Configure Capture Session 

- (void)setUpCaptureSession 
{ 
self.captureSession = [[AVCaptureSession alloc] init]; 


NSError *error; 

// Set up hardware devices 
AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 
if (videoDevice) { 
    AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error]; 
    if (input) { 
     [self.captureSession addInput:input]; 
     self.activeVideoInput = input; 
    } 
} 
AVCaptureDevice *audioDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio]; 
if (audioDevice) { 
    AVCaptureDeviceInput *audioInput = [AVCaptureDeviceInput deviceInputWithDevice:audioDevice error:&error]; 
    if (audioInput) { 
     [self.captureSession addInput:audioInput]; 
    } 
} 

//Create a VideoDataOutput and add it to the session 
AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc] init]; 
[self.captureSession addOutput:output]; 

// Setup the still image file output 
AVCaptureStillImageOutput *stillImageOutput = [[AVCaptureStillImageOutput alloc] init]; 
[stillImageOutput setOutputSettings:@{AVVideoCodecKey : AVVideoCodecJPEG}]; 

if ([self.captureSession canAddOutput:stillImageOutput]) { 
    [self.captureSession addOutput:stillImageOutput]; 
} 

// Start running session so preview is available 
[self.captureSession startRunning]; 

// Set up preview layer 
dispatch_async(dispatch_get_main_queue(), ^{ 
    self.previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.captureSession]; 
    self.previewLayer.frame = self.previewView.bounds; 
    self.previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; 

    [[self.previewLayer connection] setVideoOrientation:[self currentVideoOrientation]]; 
    [self.previewView.layer addSublayer:self.previewLayer]; 
}); 

} 

#pragma mark - Start Recording 

- (IBAction)startRecording:(id)sender { 

if ([sender isSelected]) { 
    [sender setSelected:NO]; 
    [self.captureOutput stopRecording]; 

} else { 
    [sender setSelected:YES]; 

    if (!self.captureOutput) { 
     self.captureOutput = [[AVCaptureMovieFileOutput alloc] init]; 
     [self.captureSession addOutput:self.captureOutput]; 
    } 

    // Delete the old movie file if it exists 
    //[[NSFileManager defaultManager] removeItemAtURL:[self outputURL] error:nil]; 

    [self.captureSession startRunning]; 

    AVCaptureConnection *videoConnection = [self connectionWithMediaType:AVMediaTypeVideo fromConnections:self.captureOutput.connections]; 

    if ([videoConnection isVideoOrientationSupported]) { 
     videoConnection.videoOrientation = [self currentVideoOrientation]; 
    } 

    if ([videoConnection isVideoStabilizationSupported]) { 
     videoConnection.enablesVideoStabilizationWhenAvailable = YES; 
    } 

    [self.captureOutput startRecordingToOutputFileURL:[self outputURL] recordingDelegate:self]; 
} 

// Disable the toggle button if recording 
self.toggleCameraButton.enabled = ![sender isSelected]; 
} 

- (AVCaptureConnection *)connectionWithMediaType:(NSString *)mediaType fromConnections:(NSArray *)connections { 
for (AVCaptureConnection *connection in connections) { 
    for (AVCaptureInputPort *port in [connection inputPorts]) { 
     if ([[port mediaType] isEqual:mediaType]) { 
      return connection; 
     } 
    } 
} 
return nil; 
} 

#pragma mark - AVCaptureFileOutputRecordingDelegate 

- (void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error { 
if (!error) { 
    [self presentRecording]; 
} else { 
    NSLog(@"Error: %@", [error localizedDescription]); 
} 
} 

#pragma mark - Show Last Recording 

- (void)presentRecording 
{ 
    NSString *tracksKey = @"tracks"; 
    AVAsset *asset = [AVURLAsset assetWithURL:[self outputURL]]; 
    [asset loadValuesAsynchronouslyForKeys:@[tracksKey] completionHandler:^{ 
    NSError *error; 
      AVKeyValueStatus status = [asset statusOfValueForKey:tracksKey error:&error]; 
      if (status == AVKeyValueStatusLoaded) { 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil]; 
          THPlayerViewController *controller = [mainStoryboard instantiateViewControllerWithIdentifier:@"THPlayerViewController"]; 
          controller.title = @"Capture Recording"; 
          controller.asset = asset; 
          [self presentViewController:controller animated:YES completion:nil]; 
        }); 
      } 
    }]; 
} 

#pragma mark - Recoding Destination URL 

- (NSURL *)outputURL 
{ 
    NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; 
    NSLog(@"documents Directory: %@", documentsDirectory); 
    NSString *filePath = [documentsDirectory stringByAppendingPathComponent:VIDEO_FILE]; 

    NSLog(@"output url: %@", filePath); 
    return [NSURL fileURLWithPath:filePath]; 
} 

@end 

Ho trovato questo link che mostra come catturare il video in fotogrammi. Ma non sono sicuro che se catturare il video in frame mi aiuterà a inviare il video in formato h.264 al server. Questo può essere fatto, se sì allora come?

Here la persona che ha posto la domanda dice (nei commenti sotto la domanda) che è stato in grado di farlo con successo, ma non ha menzionato il modo in cui ha catturato il video.

Per favore dimmi quale tipo di dati deve essere usato per ottenere piccoli segmenti del video catturato e anche come convertire i dati catturati nel formato richiesto e inviarlo al server.

+0

Si prega di fare riferimento a questo URL sarà utile a voi. http://stackoverflow.com/questions/15518925/how-to-save-video-in-documents-folder-then-upload-to-server – saravanan

+0

Credo che lui sta chiedendo per lo streaming live non risparmiando video nella directory dei documenti e quindi invio al server. – Leena

+0

Sì. Voglio trasmettere in streaming il mio video dal vivo. –

risposta

0

È possibile utilizzare live sdk. È necessario configurare il server di streaming powered nginx. Si prega di seguire questo link. L'ho usato ed è una soluzione molto efficiente. https://github.com/ltebean/Live