简体   繁体   中英

append or concatenate audio files in swift

Hi I want to append voice files.

I'm recording voice with AVAudioRecorder, but to play the recording I need to call "stop", but after playing it I want to continue record. Like the native iOS Voice memo app.

Should I use AVMutableCompositionTrack and how do I do that in swift? Thanks!

If you are looking to simply pause your recording and continue it later you can use AVAudioRecorder's pause() function rather than stop() and it will continue the recording when you use play() again.

However, if you are looking to actually concatenate audio files, you can do it like this:

func concatenateFiles(audioFiles: [NSURL], completion: (concatenatedFile: NSURL?) -> ()) {
    guard audioFiles.count > 0 else {
        completion(concatenatedFile: nil)
        return
    }

    if audioFiles.count == 1 {
        completion(concatenatedFile: audioFiles.first)
        return
    }

    // Concatenate audio files into one file
    var nextClipStartTime = kCMTimeZero
    let composition = AVMutableComposition()
    let track = composition.addMutableTrackWithMediaType(AVMediaTypeAudio, preferredTrackID: kCMPersistentTrackID_Invalid)

    // Add each track
    for recording in audioFiles {
        let asset = AVURLAsset(URL: NSURL(fileURLWithPath: recording.path!), options: nil)
        if let assetTrack = asset.tracksWithMediaType(AVMediaTypeAudio).first {
            let timeRange = CMTimeRange(start: kCMTimeZero, duration: asset.duration)
            do {
                try track.insertTimeRange(timeRange, ofTrack: assetTrack, atTime: nextClipStartTime)
                nextClipStartTime = CMTimeAdd(nextClipStartTime, timeRange.duration)
            } catch {
                print("Error concatenating file - \(error)")
                completion(concatenatedFile: nil)
                return
            }
        }
    }

    // Export the new file
    if let exportSession = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetPassthrough) {
        let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
        let documents = NSURL(string: paths.first!)

        if let fileURL = documents?.URLByAppendingPathComponent("file_name.caf") {
            // Remove existing file
            do {
                try NSFileManager.defaultManager().removeItemAtPath(fileURL.path!)
                print("Removed \(fileURL)")
            } catch {
                print("Could not remove file - \(error)")
            }

            // Configure export session output
            exportSession.outputURL = NSURL.fileURLWithPath(fileURL.path!)
            exportSession.outputFileType = AVFileTypeCoreAudioFormat

            // Perform the export
            exportSession.exportAsynchronouslyWithCompletionHandler() { handler -> Void in
                if exportSession.status == .Completed {
                    print("Export complete")
                    dispatch_async(dispatch_get_main_queue(), {
                        completion(file: fileURL)
                    })
                    return
                } else if exportSession.status == .Failed {
                    print("Export failed - \(exportSession.error)")
                }

                completion(concatenatedFile: nil)
                return
            }
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM