短い(1〜5秒)AVAsset
sのシーケンスを多数必要とするプロジェクト(n = 30以下で問題が表示される)に取り組んでいます。参考資料とサンプルプロジェクトのすべてで、コンポジショントラックへの挿入に範囲CMTimeRange(start: .zero, end: asset.duration)
を使用するポイントを見つけることができます。
let audioTrack: AVAssetTrack = ...
let videoTrack: AVAssetTrack = ...
var playhead = CMTime.zero
for asset in assets {
let assetRange = CMTimeRange(start: .zero, end: asset.duration)
let (sourceAudioTrack, sourceVideoTrack) = sourceTracks(from: asset)
try! audioTrack.insertTimeRange(assetRange, of: sourceAudioTrack, at: playhead)
try! videoTrack.insertTimeRange(assetRange, of: sourceVideoTrack, at: playhead)
playhead = playhead + assetRange.duration
}
問題は、これによりオーディオとビデオの同期が失われることです(ビデオがオーディオより遅れているように見えます)。
時間範囲を計算するためのいくつかの異なる戦略をテストしましたが、どれも問題を解決していないようです:
enum CompositionStrategy: Int, CaseIterable {
case each // Time range of source video track for video track, audio for audio
case videoTimeRange // Time range of source video track for both
case audioTimeRange // Time range of source audio track for both
case intersection // Intersection of source video and audio time ranges for both
case assetDuration // (start: .zero, end: asset.duration) for both
case trim // Apply audio trim from CoreMedia attachments: https://stackoverflow.com/a/33907747/266711
}
private static func calculateTimeRanges(strategy: CompositionStrategy, audioRange: CMTimeRange, videoRange: CMTimeRange, audioTrimFromStart: CMTime, audioTrimFromEnd: CMTime, assetDuration: CMTime) -> (video: CMTimeRange, audio: CMTimeRange) {
switch strategy {
case .each:
return (video: videoRange, audio: audioRange)
case .audioTimeRange:
return (video: audioRange, audio: audioRange)
case .videoTimeRange:
return (video: videoRange, audio: videoRange)
case .intersection:
let startTime = max(audioRange.start, videoRange.start)
let endTime = min(audioRange.end, videoRange.end)
let range = CMTimeRange(start: startTime, end: endTime)
return (video: range, audio: range)
case .assetDuration:
let range = CMTimeRange(start: .zero, duration: assetDuration)
return (video: range, audio: range)
case .trim:
let audioStart = audioRange.start + audioTrimFromStart
let audioEnd = audioRange.end - audioTrimFromEnd
let trimmedAudio = CMTimeRange(start: audioStart, end: audioEnd)
return (video: videoRange, audio: trimmedAudio)
}
}
(以前のスニペットの再生ヘッドの増分は、オーディオとビデオの時間範囲が異なる場合に計算されたものの最大値によって増分されます)
これらの戦略のどれも問題を解決せず、私はAppleに連絡しようとしていますが、私が見逃した簡単な何かがあることを望んでいます。私はiMovieについてもMacと同期問題なしでこれらのクリップを完全に並べることができますが、プレビュープレーヤーをバックアップするためにAVComposition
を使用しているようには見えません。
@Jeff、Appleのドキュメントを確認したかどうかはわかりませんが、プロセスでサイレントサンプルが削除されなかった場合に正確に2112サンプルで発生する可能性がある遅延について言及しているため、再生システムで2か所で手動で削除することを提案します。-最初に再生が開始されたとき-再生位置が別の場所に移動されたとき-たとえば、ユーザーがメディアの別の場所にスキップまたはスキップしてから再生を開始しますその新しい場所
https://developer.Apple.com/library/archive/technotes/tn2258/_index.html
それでも問題が解決しない場合は、使用しているテクノロジー、実装のタイプの詳細を教えてください。