2017-01-20 3 views
2

scaleTimeRange(timeRange: CMTimeRange, toDuration duration: CMTime) 방법은 비디오에 슬로우 모션 효과를 적용하려는 경우 매우 효과적입니다.비디오의 일부분 만 ScaleTimeRange

그러나 전체 비디오의 지속 시간에 적용하면 만 작동한다는 것을 알았습니다. 임의의 timeRange (예 : CMTimeRangeMake(_ start: 2, duration: 3)이 전달되면 메서드가 전혀 작동하지 않는 것 같습니다.

Q 1가)에이 scaleTimeRange 방법을 적용 할 수있는 방법이 있나요 - 또는 MP4 비디오를 내보낼 때 즉, 그것은 (0시 0분 5초 0시 0분 2초에서) 원하는 슬로우 모션 효과가 없습니다 비디오의 일부분 만? 그렇다면 어떻게 할 수 있습니까?

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

를 "방법은 전혀 작동하지 않는 것?" – shallowThought

+0

비디오는 성공적으로 저장되지만 슬로우 모션 효과는 없습니다. 내 보낸 mp4 파일은 소스 mp4 파일과 동일하며 프레임 속도가 동일합니다. –

+0

'CMTime' 값은 무엇입니까? 관련 코드를 게시 할 수 있습니까? – shallowThought

답변

1

내 생각 엔 그것이 "제대로"일하고있어,하지만 당신은 둔화되는 비디오의 일부가 예상보다 훨씬 작은, 많은 것입니다.

CMTime은 매우 특이한 데이터 구조이므로 머리를 감싸는 것은 매우 혼란 스러울 수 있습니다. tstStartTimetstDuration 변수를 구성하는 데 사용하는 videoDuration.timescale의 값은 무엇입니까? 해당 시간 표시 값이 클수록 CMTime 값으로 표시되는 시간 부분이 더 작습니다.

예를 들어 시간 눈금이 4 인 경우 CMTime(value: 2, timescale: 4)2/4 초 또는 0.5 초를 나타냅니다.

자세한 내용은 CMTime에 대한 설명서를 참조하십시오 정확히 isue을 무엇 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 '에 대한 이해를 깊게해야 할 것입니다. –

관련 문제