Domanda

Sto usando AvasseTreader per ottenere i singoli frame da un file video. Vorrei sapere come posso riprodurre l'audio dal file MP4.

Il valore di ritorno del metodo [playing play] è falso, quindi non c'è suono da suonare, ma perché

Grazie.

Crea AvasseTreader

  NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"zhang" ofType:@"mp4"]];
    AVURLAsset *avasset = [[AVURLAsset alloc] initWithURL:url options:nil];
    AVAssetTrack *track1 = [[avasset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];

NSMutableDictionary *dic2 = [NSMutableDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:kAudioFormatLinearPCM], AVFormatIDKey,  [NSNumber numberWithInt:16],AVLinearPCMBitDepthKey,
                             [NSNumber numberWithBool:NO],AVLinearPCMIsBigEndianKey,
                             [NSNumber numberWithBool:NO],AVLinearPCMIsFloatKey,
                             [NSNumber numberWithBool:NO],AVLinearPCMIsNonInterleaved, nil]; 

output1 = [[AVAssetReaderTrackOutput alloc] initWithTrack:track1 outputSettings:dic2];

AVAssetReader *reader = [[AVAssetReader alloc] initWithAsset:avasset error:nil];

[reader addOutput:output1];
[reader startReading];

Il codice di output è il seguente:

  CMSampleBufferRef sample = [output1 copyNextSampleBuffer];
    CMBlockBufferRef blockBufferRef = CMSampleBufferGetDataBuffer(sample);

    size_t length = CMBlockBufferGetDataLength(blockBufferRef);
    UInt8 buffer[length];
    CMBlockBufferCopyDataBytes(blockBufferRef, 0, length, buffer);

    NSData * data = [[NSData alloc] initWithBytes:buffer length:length];
    NSString *docDirPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString *filePath = [NSString stringWithFormat:@"%@/test.mp3", docDirPath];
    [data writeToFile:filePath atomically:YES];
    [data release];

    NSError *error;
    NSURL *fileURL = [NSURL fileURLWithPath:filePath];
    AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:&error];
    player.numberOfLoops = 0;
    [player play];
È stato utile?

Soluzione

Un'opzione sarebbe quella di evitare di utilizzare l'avaudioplayer e utilizzare invece i dati PCM che hai decodificato per riempire un Audioqueue per output.

Il metodo ideale sarebbe quello di creare un AvComposition dalla traccia audio di un Avasset Questo è stato creato dal tuo file MP4 di origine. Quella AvComposition (come sottoclasse di Avasset) può essere utilizzata all'interno di un Avplayer, che riprodurrà solo la traccia audio per te.

Non sei in grado di scrivere semplicemente blocchi di dati PCM in un file con l'estensione ".mp3", che è un formato codificato. Avaudioplayer cercherà alcuni dati codificati nel file e il file che hai scritto sarà incompatibile, motivo per cui stai ricevendo un valore di ritorno di False. Se hai il cuore impostato su come scrivere l'audio su un file, usa un AvassetWriter con le impostazioni appropriate. Questo potrebbe essere scritto come file audio di base per le massime prestazioni. Questo passaggio potrebbe anche codificare l'audio come un altro formato (diciamo, MP3 o AAC), tuttavia questo avrà un costo di prestazioni pesanti ad esso associato, ed è probabile che non sia adatto alla riproduzione in tempo reale.

Altri suggerimenti

Le risorse non sono giocabili immediatamente. È necessario osservare il valore dello stato usando l'osservazione del valore chiave. Fare riferimento al campione AVCAM di Apple.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top