Comportamiento extraño de AVMutableComposition cuando los auriculares están conectados

Tengo una aplicación que transmite files mov. Una de las características de mi aplicación es grabar audio a través de estos files transmitidos. Para lograrlo, descargo el file transmitido en segundo plano y luego comienzo la grabación de audio para capturar el audio del usuario. Una vez que el usuario está hecho, tomo el audio grabado y lo fusiono con el file mov que descargué previamente en segundo plano.

Todo esto funciona bien, excepto cuando enchufas auriculares. La experiencia es la misma, pero cuando vas a reproducir la grabación solo se capturó el audio. El file mov nunca lo convierte en el activo final, no estoy seguro de por qué.

Así es como estoy produciendo la grabación:

let video = AVAsset(URL: currentCacheUrl) let audioRecording = AVAsset(URL: currentRecordingUrl) // 1 - Create AVMutableComposition object. This object will hold your AVMutableCompositionTrack instances. let mixComposition = AVMutableComposition() // 2 - Video track let videoTrack = mixComposition.addMutableTrackWithMediaType(AVMediaTypeVideo, prefernetworkingTrackID: kCMPersistentTrackID_Invalid) do { try videoTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, audioRecording.duration), ofTrack: video.tracksWithMediaType(AVMediaTypeVideo)[0], atTime: kCMTimeZero) } catch _ { print("Failed to load video track") } // 3 - Audio track let audioTrack = mixComposition.addMutableTrackWithMediaType(AVMediaTypeAudio, prefernetworkingTrackID: 0) do { try audioTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, audioRecording.duration), ofTrack: audioRecording.tracksWithMediaType(AVMediaTypeAudio)[0], atTime: kCMTimeZero) } catch _ { print("Failed to load audio track") } // 4 - Get path let recordingsPath = MisueroKaraokeLatinoHelper.Variables.getRecordingsDirectory let currentDate = NSDate() let date = formatDate(currentDate) let savePath = recordingsPath.URLByAppendingPathComponent("\(date).mov") // 5 - Create Exporter guard let exporter = AVAssetExportSession(asset: mixComposition, presetName: AVAssetExportPresetHighestQuality) else { return } exporter.outputURL = savePath exporter.outputFileType = AVFileTypeQuickTimeMovie exporter.shouldOptimizeForNetworkUse = true // 6 - Perform the Export exporter.exportAsynchronouslyWithCompletionHandler() { dispatch_async(dispatch_get_main_queue()) { _ in print("save and merge complete") let recording = Recording(title: self.currentRecordSong.title, artist: self.currentRecordSong.artist, genre: self.currentRecordSong.genre, timestamp: currentDate, fileUrl: savePath) MisueroKaraokeLatinoHelper.Variables.Recordings.append(recording) MisueroKaraokeLatinoHelper.Variables.Recordings.sortInPlace({$0.timestamp.compare($1.timestamp) == NSComparisonResult.OrdenetworkingDescending}) let recordingsData = NSKeyedArchiver.archivedDataWithRootObject(MisueroKaraokeLatinoHelper.Variables.Recordings) NSUserDefaults.standardUserDefaults().setObject(recordingsData, forKey: "Recordings") } } 

Algo similar sucede cuando el dispositivo iOS tiene su salida de audio configurada en un dispositivo Bluetooth. La grabación final captura el audio grabado por el usuario y el video en el file mov, pero no el audio en el file mov. ¿Lo que da?

addMutableTrackWithMediaType agrega una pista del tipo de medio especificado. Al especificar AVMediaTypeVideo cuando agrego la pista de video, SOLO agrega la pista de video. Por lo tanto, cuando los auriculares no están enchufados, la grabadora de audio retoma el audio del mov que se está reproduciendo; sin embargo, cuando los auriculares están enchufados, el micrófono no puede reproducir la reproducción de audio a través de los auriculares.

La solución es agregar la pista de audio y video del file mov almacenado en caching y hacer frente al retraso / synchronization de todas las pistas. El audio del mov almacenado en caching también debería agregarse condicionalmente si los auriculares están enchufados o si la salida de audio en el dispositivo está configurada de manera similar a un altavoz bluetooth, en cuyo caso la grabadora de audio no podrá captar ese audio tan limpio.

Abierto a otras soluciones / sugerencias. Pero este enfoque está funcionando para mí por ahora.