【问题标题】:How to record a video and make it slow motion如何录制视频并使其慢动作
【发布时间】:2011-09-17 23:34:40
【问题描述】:

我正在为学校开发一款 iPhone 应用程序,需要一些帮助。该应用程序应录制视频,使其慢动作(约 2 倍),然后将其保存到照片库。到目前为止,除了如何制作视频慢动作之外,我拥有一切。我知道这是可以做到的,因为 App Store 中已经有一个应用程序可以做到这一点。

如何将我保存到临时 URL 的视频拍摄并调整速度,然后再将其保存到照片库?

【问题讨论】:

标签: iphone ios4 video-capture


【解决方案1】:

如果您需要导出视频,则需要使用AVMutableComposition Class

然后将您的视频以AVAsset 的形式添加到AVMutableComposition 并使用以下方法对其进行缩放:

- (void)scaleTimeRange:(CMTimeRange)timeRange toDuration:(CMTime)duration

最后你使用AVAssetExportSession Class 导出它

【讨论】:

  • 我很困惑如何使用它来制作视频慢动作?
【解决方案2】:

slowmoVideo 是一个 OSS 项目,它似乎可以很好地做到这一点,尽管我不知道它是否可以在 iPhone 上运行。

它不仅仅是让您的视频以 0.01 倍的速度播放。你可以 平滑地减慢和加快您的镜头,可选地与运动 模糊。慢动作是如何工作的? slowmoVideo 试图找出在哪里 像素在视频中移动(此信息称为光流), 然后使用此信息来计算额外的帧。

【讨论】:

    【解决方案3】:

    我编写了一个代码,可以让您的视频以“慢动作”呈现,并将其保存在照片库中。 “这段代码在 Swift 5 中工作的主要内容”。在 iOS swift 中创建“慢动作”视频并不容易,我遇到了许多“慢动作”,他们知道它们无法正常工作,或者其中的一些代码已被贬值。所以我终于找到了一种在 Swift 中制作慢动作的方法。 此代码可用于 120fps 也比这更大。只需添加视频的网址并使其变慢

    这是“我为实现慢动作而创建的代码 sn-p”

    如果此代码有效,请给我一个 UPVOTE。

            func slowMotion(pathUrl: URL) {
    
        let videoAsset = AVURLAsset.init(url: pathUrl, options: nil)
        let currentAsset = AVAsset.init(url: pathUrl)
    
        let vdoTrack = currentAsset.tracks(withMediaType: .video)[0]
        let mixComposition = AVMutableComposition()
    
        let compositionVideoTrack = mixComposition.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid)
    
        let videoInsertError: Error? = nil
        var videoInsertResult = false
        do {
            try compositionVideoTrack?.insertTimeRange(
                CMTimeRangeMake(start: .zero, duration: videoAsset.duration),
                of: videoAsset.tracks(withMediaType: .video)[0],
                at: .zero)
            videoInsertResult = true
        } catch let videoInsertError {
        }
    
        if !videoInsertResult || videoInsertError != nil {
            //handle error
            return
        }
    
    
        var duration: CMTime = .zero
        duration = CMTimeAdd(duration, currentAsset.duration)
        
        
        //MARK: You see this constant (videoScaleFactor) this helps in achieving the slow motion that you wanted. This increases the time scale of the video that makes slow motion
        // just increase the videoScaleFactor value in order to play video in higher frames rates(more slowly)
        let videoScaleFactor = 2.0
        let videoDuration = videoAsset.duration
        
        compositionVideoTrack?.scaleTimeRange(
            CMTimeRangeMake(start: .zero, duration: videoDuration),
            toDuration: CMTimeMake(value: videoDuration.value * Int64(videoScaleFactor), timescale: videoDuration.timescale))
        compositionVideoTrack?.preferredTransform = vdoTrack.preferredTransform
        
        let dirPaths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).map(\.path)
        let docsDir = dirPaths[0]
        let outputFilePath = URL(fileURLWithPath: docsDir).appendingPathComponent("slowMotion\(UUID().uuidString).mp4").path
        
        if FileManager.default.fileExists(atPath: outputFilePath) {
            do {
                try FileManager.default.removeItem(atPath: outputFilePath)
            } catch {
            }
        }
        let filePath = URL(fileURLWithPath: outputFilePath)
        
        let assetExport = AVAssetExportSession(
            asset: mixComposition,
            presetName: AVAssetExportPresetHighestQuality)
        assetExport?.outputURL = filePath
        assetExport?.outputFileType = .mp4
        
        assetExport?.exportAsynchronously(completionHandler: {
            switch assetExport?.status {
            case .failed:
                print("asset output media url = \(String(describing: assetExport?.outputURL))")
                print("Export session faiied with error: \(String(describing: assetExport?.error))")
                DispatchQueue.main.async(execute: {
                    // completion(nil);
                })
            case .completed:
                print("Successful")
                let outputURL = assetExport!.outputURL
                print("url path = \(String(describing: outputURL))")
                
                PHPhotoLibrary.shared().performChanges({
                    PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: outputURL!)
                }) { saved, error in
                    if saved {
                        print("video successfully saved in photos gallery view video in photos gallery")
                    }
                    if (error != nil) {
                        print("error in saing video \(String(describing: error?.localizedDescription))")
                    }
                }
                DispatchQueue.main.async(execute: {
                    //      completion(_filePath);
                })
            case .none:
                break
            case .unknown:
                break
            case .waiting:
                break
            case .exporting:
                break
            case .cancelled:
                break
            case .some(_):
                break
            }
        })
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-01
      • 1970-01-01
      • 2013-06-22
      • 1970-01-01
      • 2020-08-07
      • 2013-08-04
      • 2013-09-28
      • 1970-01-01
      相关资源
      最近更新 更多