2017-11-27 5 views
0

AVCaptureDeviceFormatを変更した後、240fpsビデオを記録しました。そのビデオを写真ライブラリに保存すると、スローモ効果がそこにあります。しかし、私がAVPlayerを使ってドキュメントディレクトリからそのファイルを再生すると、私はスローモ効果を見ることができません。動画を再生するにはiOS AVPlayer cant play 240 fps video

コード:

AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:[AVAsset assetWithURL:[NSURL fileURLWithPath:fullPath]]]; 

    AVPlayer *feedVideoPlayer = [AVPlayer playerWithPlayerItem:playerItem]; 

    AVPlayerViewController *playerController = [[AVPlayerViewController alloc] init]; 

playerController.view.frame = CGRectMake(0, 0, videoPreviewView.frame.size.width, videoPreviewView.frame.size.height); 

playerController.player = feedVideoPlayer; 
+0

[iOS AVPlayerスローダウン]の可能な複製(https://stackoverflow.com/questions/37249146/ios-avplayer-slow-down) – the4kman

答えて

0

それは少し迷惑なんだが、私はあなたが品質を失いたくない場合は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に変換する手助けが必要な場合はお知らせください。しかし、これは比較的単純です。

関連する問題