2011-08-17 17 views
5

Sto cercando di trovare il modo migliore per caricare video da un iPhone (iOS5) il più velocemente possibile - se possibile in tempo reale.Near Real Time Caricamento video da iPhone

Ho trovato questa domanda precedente e la risposta molto utile.
streaming video FROM an iPhone

Ma mi ha lasciato diverse domande senza risposta. Non ho abbastanza rappresentanti per pubblicare commenti in quella domanda- e penso che le mie domande vadano comunque oltre lo scopo della domanda originale.

Quindi:

  1. Sta utilizzando AVCaptureSession/AVAssetWriter e tagliare il video in brevi clip il modo migliore per muoversi rapidamente (compresso) il video al largo di iPhone - quasi in tempo reale?

  2. In tal caso, qualcuno potrebbe fornire ulteriori dettagli su come utilizzare due AVAssetWriters e una coda in background per evitare interruzioni (come utente Steve McFarlin menziona nella domanda di riferimento sopra)? Non sono chiaro come funzionerebbe il trasferimento da un AVAssetWriter a un altro ...

  3. (Critico) Esiste un modo semplice per aggiungere nuovamente i file video tagliati a un video a lunghezza intera ... o almeno essere in grado di suonarli come se fossero un video completo? Avrei bisogno di unire i file più piccoli per apparire come un file sia sul server E sull'iPhone (per l'anteprima).

Grazie per qualsiasi aiuto ...

+0

Non puoi chiedere questo tipo di domande in pubblico. Come sei a) costruttori iOS convincenti a rompere la loro NDA con Apple, eb) se sei anche tu uno sviluppatore iOS a pagamento, rompendo la tua NDA con Apple. Sarebbe saggio/prudente restringere i tuoi post di sviluppo iOS 5 ai forum ufficiali ** privati ​​** e ** riservati ** ospitati da Apple. – twilson

+0

Se non sei uno sviluppatore iOS a pagamento, non hai spazio per utilizzare l'SDK beta di iOS 5, e dovrai farlo fino a quando Apple non rilascerà iOS 5 corretto! – twilson

risposta

4

Ebbene si può provare a fare il buffer al telefono ma che sembra controproducente per me, dato che ha limitato la memoria. Vorrei provare a configurare una AVCaptureSession e utilizzare AVCaptureVideoDataOutput che venderà i frame su un thread dispatch_queue separato (se configurato li venderà come frame MPEG). Quel thread può consegnare i frame a una presa asincrona per trasmettere, possibilmente con una piccola intestazione che indica il numero di fotogramma e il formato video. In alternativa è possibile trasferire i dati a un thread di invio tramite una coda che consente di monitorare quanti frame sono in attesa di essere trasmessi.

Sul server ricevente, dovresti occuparti di creare un buffer piccolo (diciamo alcuni secondi) e fare il riordino del frame se arrivano fuori servizio.

Il grosso problema è quello di rilevare la larghezza di banda e sapere quando rilasciare la qualità verso il basso in modo da non finire con un arretrato di pacchetti in attesa di uscire. Questo è un argomento completamente diverso e complicato :) La chiave sarà nella selezione se codec, qualità e dimensione del video ... che determinerà direttamente la larghezza di banda necessaria per trasmettere i frame in tempo reale. AVVideoCodecH264 è supportato nell'hardware in determinate modalità ed è probabilmente l'unica opzione realistica per la codifica in tempo reale.

Non penso che troverete un esempio già pronto per questo, poiché rappresenta un sacco di lavoro per funzionare correttamente.

+0

c'è qualche API propper per leggere i dati dei frammenti dei supporti e per recuperare il timestamp, –

0

2) Ecco come ho Chunked i file senza perdere troppi fotogrammi:

- (void) segmentRecording:(NSTimer*)timer { 
    AVAssetWriter *tempAssetWriter = self.assetWriter; 
    AVAssetWriterInput *tempAudioEncoder = self.audioEncoder; 
    AVAssetWriterInput *tempVideoEncoder = self.videoEncoder; 
    self.assetWriter = queuedAssetWriter; 
    self.audioEncoder = queuedAudioEncoder; 
    self.videoEncoder = queuedVideoEncoder; 
    //NSLog(@"Switching encoders"); 

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ 
     [tempAudioEncoder markAsFinished]; 
     [tempVideoEncoder markAsFinished]; 
     if (tempAssetWriter.status == AVAssetWriterStatusWriting) { 
      if(![tempAssetWriter finishWriting]) { 
       [self showError:[tempAssetWriter error]]; 
      } 
     } 
     if (self.readyToRecordAudio && self.readyToRecordVideo) { 
      NSError *error = nil; 
      self.queuedAssetWriter = [[AVAssetWriter alloc] initWithURL:[self newMovieURL] fileType:(NSString *)kUTTypeMPEG4 error:&error]; 
      if (error) { 
       [self showError:error]; 
      } 
      self.queuedVideoEncoder = [self setupVideoEncoderWithAssetWriter:self.queuedAssetWriter formatDescription:videoFormatDescription bitsPerSecond:videoBPS]; 
      self.queuedAudioEncoder = [self setupAudioEncoderWithAssetWriter:self.queuedAssetWriter formatDescription:audioFormatDescription bitsPerSecond:audioBPS]; 
      //NSLog(@"Encoder switch finished"); 

     } 
    }); 
} 

https://github.com/chrisballinger/FFmpeg-iOS-Encoder/blob/master/AVSegmentingAppleEncoder.m

3) Ecco uno script per concatenare i file sul server

import glob 
import os 
run = os.system # convenience alias 


files = glob.glob('*.mp4') 
out_files = [] 

n = 0 
for file in files: 
    out_file = "out-{0}.ts".format(n) 
    out_files.append(out_file) 
    full_command = "ffmpeg -i {0} -f mpegts -vcodec copy -acodec copy -vbsf h264_mp4toannexb {1}".format(file, out_file) 
    run(full_command) 
    n += 1 

out_file_concat = '' 
for out_file in out_files: 
    out_file_concat += ' {0} '.format(out_file) 

cat_command = 'cat {0} > full.ts'.format(out_file_concat) 
print cat_command 
run(cat_command) 
run("ffmpeg -i full.ts -f mp4 -vcodec copy -acodec copy -absf aac_adtstoasc full.mp4") 

https://github.com/chrisballinger/FFmpeg-iOS-Encoder/blob/master/concat-mp4.py

+0

Ehi come accedere a questi segmenti chunked e trasmetterli in streaming con nssstream al server quindi ad altri dispositivi ios? – sajwan

+0

Se 'assetWriter' ha completato correttamente la scrittura, è possibile che sia possibile effettuare una chiamata delegata per caricare i segmenti e quindi interrompere la registrazione caricando l'ultimo? O mi sta sfuggendo qualcosa? – HighFlyingFantasy

Problemi correlati