それは少し迷惑なんだが、私はあなたが品質を失いたくない場合はAVComposition
でビデオを再作成する必要があります信じています。私は別の方法があるかどうかを知りたいですが、これが私が思いついたものです。技術的には、AVAssetExportSession経由でビデオを書き出すことはできますが、パススルー品質を使用すると、同じビデオファイルが生成され、動きは遅くなりません。トランスコードする必要があります(AFAIK。その解決方法については、Issue playing slow-mo AVAsset in AVPlayerを参照してください) 。
最初に行う必要があるのは、ソースメディアの元のタイムマッピングオブジェクトを取得することです。あなたはそのようにそれを行うことができます。
let options = PHVideoRequestOptions()
options.version = PHVideoRequestOptionsVersion.current
options.deliveryMode = .highQualityFormat
PHImageManager().requestAVAsset(forVideo: phAsset, options: options, resultHandler: { (avAsset, mix, info) in
guard let avAsset = avAsset else { return }
let originalTimeMaps = avAsset.tracks(withMediaType: AVMediaTypeVideo)
.first?
.segments
.flatMap { $0.timeMapping } ?? []
}
あなたは、元のメディア(ドキュメントディレクトリに座っ1)のtimeMappingsを持っていたら、あなたはそのメディアのURLとご希望のオリジナルCMTimeMappingオブジェクトに渡すことができます再作成する。その後、AVPlayerで再生する準備のできた新しいAVCompositionを作成します。あなたがそのあなたCMTimeMapping
オブジェクトを尊重すべき、AVPlayer
でプレーする準備ができていることをあなたにAVComposition
を与えるためにあなたのCompositionMapper
クラスのcompose()
機能を使用することができます
class CompositionMapper {
let url: URL
let timeMappings: [CMTimeMapping]
init(for url: URL, with timeMappings: [CMTimeMapping]) {
self.url = url
self.timeMappings = timeMappings
}
init(with asset: AVAsset, and timeMappings: [CMTimeMapping]) {
guard let asset = asset as? AVURLAsset else {
print("cannot get a base URL from this asset.")
fatalError()
}
self.timeMappings = timeMappings
self.url = asset.url
}
func compose() -> AVComposition {
let composition = AVMutableComposition(urlAssetInitializationOptions: [AVURLAssetPreferPreciseDurationAndTimingKey: true])
let emptyTrack = composition.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: kCMPersistentTrackID_Invalid)
let audioTrack = composition.addMutableTrack(withMediaType: AVMediaTypeAudio, preferredTrackID: kCMPersistentTrackID_Invalid)
let asset = AVAsset(url: url)
guard let videoAssetTrack = asset.tracks(withMediaType: AVMediaTypeVideo).first else { return composition }
var segments: [AVCompositionTrackSegment] = []
for map in timeMappings {
let segment = AVCompositionTrackSegment(url: url, trackID: kCMPersistentTrackID_Invalid, sourceTimeRange: map.source, targetTimeRange: map.target)
segments.append(segment)
}
emptyTrack.preferredTransform = videoAssetTrack.preferredTransform
emptyTrack.segments = segments
if let _ = asset.tracks(withMediaType: AVMediaTypeVideo).first {
audioTrack.segments = segments
}
return composition.copy() as! AVComposition
}
:あなたは、これに似たクラスが必要になります
これをObjective-Cに変換する手助けが必要な場合はお知らせください。しかし、これは比較的単純です。
[iOS AVPlayerスローダウン]の可能な複製(https://stackoverflow.com/questions/37249146/ios-avplayer-slow-down) – the4kman