2017-01-20 5 views
2

scaleTimeRange(timeRange: CMTimeRange, toDuration duration: CMTime)メソッドは、ビデオにスローモーションエフェクトを適用する場合は非常に効果的です。ビデオの一部のみのScaleTimeRange

しかし、は、ビデオ全体に適用された場合にのみ動作します。の再生時間です。任意のtimeRange、たとえばCMTimeRangeMake(_ start: 2, duration: 3)が渡されても、メソッドはまったく動作していないようです。

Q 1が)に、このscaleTimeRange方法を適用する方法はあります - のMP4動画がエクスポートされた場合、すなわち、それは、(夜十二時00分05秒午後十二時00分02秒から)は、所望のスローモーション効果を持っていません。ビデオの一部だけ?もしそうなら、それはどうやって行えますか?

Q2)そうでない場合、このスローモーションエフェクトをビデオの一部にどのように適用できますか?他の方法はありますか?

CODE

var asset: AVAsset? 


func setupAsset(){ 

let videoAsset = AVURLAsset(url: Bundle.main.url(forResource: "Sample", withExtension: "mp4")!) 

let comp = AVMutableComposition() 

let videoAssetSourceTrack = videoAsset.tracks(withMediaType: AVMediaTypeVideo).first! as AVAssetTrack 


let videoCompositionTrack = comp.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: kCMPersistentTrackID_Invalid) 


do { 

    try videoCompositionTrack.insertTimeRange(
     CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(9 , 600)), 
     of: videoAssetSourceTrack, 
     at: kCMTimeZero) 


    let videoScaleFactor = Int64(3.0) 
    let videoDuration: CMTime = videoAsset.duration 



    let tstStartTime = CMTime(value: 2, timescale: videoDuration.timescale) 
    let tstDuration = CMTime(value: 1 , timescale: videoDuration.timescale) 

    //1. Applies slow motion correctly (to entire video) 

    videoCompositionTrack.scaleTimeRange(CMTimeRangeMake(kCMTimeZero , videoDuration), toDuration: CMTimeMake(videoDuration.value * videoScaleFactor, videoDuration.timescale)) 

    //2. Replace with 1 , the exported video plays as is with no slow motion effect 

    videoCompositionTrack.scaleTimeRange(CMTimeRangeMake(kCMTimeZero , tstDuration), toDuration: CMTimeMake(tstDuration.value * videoScaleFactor, videoDuration.timescale)) 

    // 3. Replace with 1, unexpected behaviour : video only displays first frame for CMTimeMakes's value then proceeds to play video normally. 
    videoCompositionTrack.scaleTimeRange(CMTimeRangeMake(tstStartTime , tstDuration), toDuration: CMTimeMake(tstDuration.value * videoScaleFactor, videoDuration.timescale)) 



    videoCompositionTrack.preferredTransform = videoAssetSourceTrack.preferredTransform 



}catch { print(error) } 

asset = comp 
} 
+0

isueは「方法が全く動作していないよう」され、正確には何? – shallowThought

+0

ビデオは正常に保存されますが、スローモーションエフェクトはありません。 エクスポートされたmp4ファイルは、同じフレームレートのソースmp4ファイルと同じです。 –

+0

'CMTime'sの値は何ですか?関連コードを投稿してもらえますか? – shallowThought

答えて

1

私の推測では、それが「正しく」働いているということですが、あなたが減速しているビデオの部分は、あなたが予想よりもはるかに小さい、くらいです。

CMTimeは非常に珍しいデータ構造です。そのため、あなたの頭を包むのは非常に混乱することがあります。 tstStartTimeおよびtstDuration変数を構成するために使用しているvideoDuration.timescaleの値は何ですか?そのタイムスケール値が大きいほど、CMTime値で表される時間部分が小さくなります。

たとえば、タイムスケールが4の場合、CMTime(value: 2, timescale: 4)は、2/4秒、つまり0.5秒を表します。詳細については

CMTimeのマニュアルを参照してください:https://developer.apple.com/reference/coremedia/1669288-cmtime

+0

'videoDuration.timescale'の値は600です。私は' timeScale'が何をするのかちょっと考えていますが、値が '90000'のコードを見ました。それはわかりません。なぜそのような高い価値が必要なのか。 これはリンゴのStopNGoサンプルアプリケーションのものです 'frameDuration = CMTimeMakeWithSeconds = CMTimeMake(1.0/5/0,90000)' // 5fps - 5枚の写真を撮ると1秒のビデオになります。 –

+0

そのサンプルで90000というタイムスケールを選択した理由がわかりませんが、CMTimeが動作する理由は、丸め誤差のない広範囲にわたって極めて高い精度を実現するためです。ここに、より深く説明しようとするブログ記事があります:https://warrenmoore.net/understanding-cmtime –

+1

問題を指摘してくれてありがとう。私の前提は 'scaleTimeRange'はセグメント全体ではなくビデオ全体にしか使えないかもしれないが、おそらく私は' CMTime'についての私の理解を深める必要があるだろう。 –

関連する問題