8

我正在创建我的这个应用程序并以 120 和 240 fps 的速度拍摄视频。

当我在我的 Mac 上观看这些视频时,我会在时间线下方看到这些标记。

在此处输入图像描述

这些标记是可编辑的,代表慢动作的区域。因此,视频以正常帧速率开始,进入慢动作并在结束时返回正常帧速率。我没有把那些标记放在那里,iOS 做了。在那种情况下,我想知道是否有办法删除它们并使视频完全慢动作。

我只是AVAssetWriter像视频非慢动作一样正常初始化。

另外,我注意到这些“慢动作”视频并不是真正的慢动作,但它们是慢动作的“食谱”,可以在 iOS 设备和使用 QuickTime X 的 Mac 上正确播放。甚至 QuickTime 7 也不能正确播放它们。

无论如何要让这个东西成为可以在任何播放器、任何计算机上播放的真正慢动作?

4

2 回答 2

4

您的“慢动作”视频文件实际上只是具有高帧率的视频文件。iOS 正在降低播放速率,以慢动作的形式展示多余的帧。问题是其他播放器以 1 的播放速率播放,因此要使效果可移植,您需要改为修改帧呈现时间戳。

您可能可以使用 an 来执行此操作,AVMutableComposition但我更喜欢使用所见即所得AVAssetReader/AVAssetWriter对。输入文件中的每一帧都是这样的:

if let inSampleBuffer = readerOutput.copyNextSampleBuffer() {
    let inTimeStamp = CMSampleBufferGetPresentationTimeStamp(inSampleBuffer)
    let outTimeStamp = CMTimeMultiplyByFloat64(inTimeStamp, 240.0/30)  // slow 240 fps down to 30fps (8x slowmo)
    var outSampleBuffer: CMSampleBuffer?
    var outTimingInfo = CMSampleTimingInfo(duration: kCMTimeInvalid, presentationTimeStamp: outTimeStamp, decodeTimeStamp: kCMTimeInvalid)

    if CMSampleBufferCreateCopyWithNewTiming(kCFAllocatorDefault, inSampleBuffer, 1, &outTimingInfo, &outSampleBuffer) == noErr {
        writerInput.appendSampleBuffer(outSampleBuffer!)
    }
} else {
    // finished
}
于 2017-04-16T23:17:42.990 回答
0

发生这种情况是因为您的视频的帧速率太高。因此 iOS 会自动将 slowMo 添加到您的视频中。对于那些正在为此问题寻找 AVComposition 解决方案的人,我发现了两个(坏)解决方案:

  • 将 AVAssetExportSession 设置为 AVAssetExportPresetMediumQuality 或更少会导致帧率下降,但质量也会变差。不好。
  • 将 AVAssetExportSession.videoComposition 设置为 frameDuration 为 CMTimeMake(1, 30) 的视频合成,但用它导出视频需要很长时间,这也不好。我不知道是什么原因导致它需要这么长时间。

第二个是目前最好的解决方案。我为此发布了一些示例代码:

   let videoComposition = AVMutableVideoComposition(propertiesOf: mixComposition)
            videoComposition.sourceTrackIDForFrameTiming = kCMPersistentTrackID_Invalid
            videoComposition.frameDuration = CMTimeMake(value: 1, timescale: 30)
            // Changes FPS to 30

            //export the video to as per your requirement conversion
            if let exportSession = AVAssetExportSession(asset: mixComposition, presetName: AVAssetExportPresetHighestQuality) {
                exportSession.videoComposition =  videoComposition
                exportSession.outputURL = outputURL
                exportSession.outputFileType = AVFileType.mp4
               
                
                /// try to export the file and handle the status cases
                exportSession.exportAsynchronously(completionHandler: {
于 2021-05-08T08:01:16.323 回答