Мы предъявляли те же требования к нашему приложению, что и описанный OP, и столкнулись с теми же проблемами (т. Е. Запись должна быть остановлена, а не приостановлена, если пользователь хочет прослушать то, что он записал до этого точка). Наше приложение ( Github repo проекта ) использует AVQueuePlayer
для воспроизведения и метод, похожий на ответ Kermitology для объединения частичных записей, с некоторыми заметными отличиями:
- реализовано в Swift
- объединяет несколько записей в одну
- нет путаницы с треками
Обоснование последнего элемента заключается в том, что в простых записях с AVAudioRecorder
будет один трек, и главная причина всего этого обходного пути - объединить эти отдельные треки в ресурсах (см. Добавление 3 ). , Так почему бы не использовать метод AVMutableComposition
insertTimeRange
вместо этого, вместо AVAssetTrack
?
вместо *1028*?
Соответствующие части: ( полный код )
import UIKit
import AVFoundation
class RecordViewController: UIViewController {
/* App allows volunteers to record newspaper articles for the
blind and print-impaired, hence the name.
*/
var articleChunks = [AVURLAsset]()
func concatChunks() {
let composition = AVMutableComposition()
/* `CMTimeRange` to store total duration and know when to
insert subsequent assets.
*/
var insertAt = CMTimeRange(start: kCMTimeZero, end: kCMTimeZero)
repeat {
let asset = self.articleChunks.removeFirst()
let assetTimeRange =
CMTimeRange(start: kCMTimeZero, end: asset.duration)
do {
try composition.insertTimeRange(assetTimeRange,
of: asset,
at: insertAt.end)
} catch {
NSLog("Unable to compose asset track.")
}
let nextDuration = insertAt.duration + assetTimeRange.duration
insertAt = CMTimeRange(start: kCMTimeZero, duration: nextDuration)
} while self.articleChunks.count != 0
let exportSession =
AVAssetExportSession(
asset: composition,
presetName: AVAssetExportPresetAppleM4A)
exportSession?.outputFileType = AVFileType.m4a
exportSession?.outputURL = /* create URL for output */
// exportSession?.metadata = ...
exportSession?.exportAsynchronously {
switch exportSession?.status {
case .unknown?: break
case .waiting?: break
case .exporting?: break
case .completed?: break
case .failed?: break
case .cancelled?: break
case .none: break
}
}
/* Clean up (delete partial recordings, etc.) */
}
Эта диаграмма помогла мне обойти то, что ожидает, что и откуда унаследовано. (NSObject
неявно подразумевается как суперкласс, где нет стрелки наследования.)
Приложение 1: У меня были оговорки относительно части switch
вместо использования KVO на AVAssetExportSessionStatus
, но документы ясно, что блок обратного вызова exportAsynchronously
вызывается, когда запись завершить или в случае ошибки записи ".
Приложение 2: На всякий случай, если у кого-то возникли проблемы с AVQueuePlayer
: 'AVPlayerItem не может быть связан с более чем одним экземпляром AVPlayer'
Приложение 3: Если вы не записываете стерео, но, насколько мне известно, мобильные устройства имеют один вход. Кроме того, использование необычного микширования звука также потребует использования AVCompositionTrack
. Хороший SO поток: Правильные AVAudioRecorder Настройки для записи голоса?