24

我需要获取(本地)视频的持续时间,然后以UIImages 访问其各个帧。到目前为止,我一直在使用MPMoviePlayerController它。

首先我注册MPMovieDurationAvailableNotification事件,然后调用prepareToPlay. 收到事件后,我会记下视频的持续时间,然后通过requestThumbnailImagesAtTimes.

这可行,但是即使我没有以任何方式将其添加到视图中,视频似乎也开始播放(我可以听到在后台播放的音频)。

有什么方法可以在不实际播放视频的情况下获取视频的持续时间和帧数?

4

4 回答 4

42

要获得持续时间:

NSURL *sourceMovieURL = [NSURL fileURLWithPath:somePath];
AVURLAsset *sourceAsset = [AVURLAsset URLAssetWithURL:sourceMovieURL options:nil];
CMTime duration = sourceAsset.duration;

要获取帧抓取:

AVAssetImageGenerator* generator = [AVAssetImageGenerator assetImageGeneratorWithAsset:destinationAsset];

//Get the 1st frame 3 seconds in
int frameTimeStart = 3;
int frameLocation = 1;

//Snatch a frame
CGImageRef frameRef = [generator copyCGImageAtTime:CMTimeMake(frameTimeStart,frameLocation) actualTime:nil error:nil];
于 2013-02-07T05:22:10.403 回答
11

你可以像这样快速进入

func getMediaDuration(url: NSURL!) -> Float64{
    let asset : AVURLAsset = AVURLAsset(URL: url) as AVURLAsset
    let duration : CMTime = asset.duration
    return CMTimeGetSeconds(duration)
}
于 2015-03-09T14:33:13.980 回答
6

setShouldAutoPlay:NO使用 MPMoviePlayerController调用可以解决问题:

 moviePlayerController = [[MPMoviePlayerController alloc] initWithContentURL: movieURL];
[moviePlayerController setShouldAutoplay:NO];   
[moviePlayerController prepareToPlay];

编辑:我在没有解释的情况下被否决了,但我会坚持这个答案。如果您需要使用,MPMoviePlayerController那么这将阻止媒体的自动播放,但仍然允许您按照我原来的问题获得持续时间和缩略图。

于 2013-02-07T04:48:14.033 回答
0

使用此方法:

class func getVideoInfo(from url: URL,
                        completion: @escaping ((_ image: UIImage?, _ duration: CGFloat?) -> Void)) {
    DispatchQueue.global().async {
        let asset = AVAsset(url: url)
        let duration = CMTimeGetSeconds(asset.duration)
        let avAssetImageGenerator = AVAssetImageGenerator(asset: asset)
        avAssetImageGenerator.appliesPreferredTrackTransform = true
        let thumnailTime = CMTimeMake(value: 2, timescale: 1)
        do {
            let cgThumbImage = try avAssetImageGenerator.copyCGImage(at: thumnailTime, actualTime: nil)
            let thumbNailImage = UIImage(cgImage: cgThumbImage)
            DispatchQueue.main.async {
                completion(thumbNailImage, duration)
            }
        } catch {
            DispatchQueue.main.async {
                completion(nil, nil)
            }
        }
    }
}
于 2021-11-23T13:43:24.447 回答