【问题标题】:iOS: get video duration and thumbnails without playing videoiOS:在不播放视频的情况下获取视频时长和缩略图
【发布时间】:2021-11-23 21:43:24
【问题描述】:

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

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

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

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

【问题讨论】:

  • 如果您将视频存储在文件系统中,那么您可以将其作为 AVAssetassetWithUrl: 访问,并且返回的 AVAsset 具有持续时间属性。不过不确定缩略图。
  • 关于这个问题的任何建议:stackoverflow.com/questions/47617130/…

标签: ios ios6


【解决方案1】:

获取持续时间:

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];

【讨论】:

  • 这确实得到了正确的持续时间,谢谢。然而,“抓帧”的时机似乎有点不对劲。我不得不使用 CMTimeMakeWithSeconds(offsetInSeconds, 600)。
  • 什么是帧时间?我看到 frameTimeStart,应该是 frameTime 吗?
【解决方案2】:

你可以像这样swift进入

func getMediaDuration(url: NSURL!) -> Float64{
    let asset : AVURLAsset = AVURLAsset(URL: url) as AVURLAsset
    let duration : CMTime = asset.duration
    return CMTimeGetSeconds(duration)
}

【讨论】:

  • func getMediaDuration(url: URL) -> Double { let asset : AVURLAsset = AVURLAsset(url: url) as AVURLAsset let duration : CMTime = asset.duration return CMTimeGetSeconds(duration) }
【解决方案3】:

调用setShouldAutoPlay:NO 可以使用 MPMoviePlayerController:

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

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

【讨论】:

  • 是否有人同意将自动播放默认设置为 TRUE 有点愚蠢?
  • 你的回答确实,嗯,回答了这个问题;但我猜你被否决了,因为你对MPMoviePlayerController 所做的事情是一个丑陋的解决方法,它可能使用比获取所需信息更多的资源,并且可能会在未来的 iOS 版本中中断。当您只需要一些关于它的元数据时,您要求系统加载到内存并准备播放视频。题外话:只是出于好奇,它会告诉你谁投了你的票吗?我从来没有被否决过,所以我很好奇。
【解决方案4】:

使用这个方法:

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)
            }
        }
    }
}

【讨论】:

    猜你喜欢
    • 2015-12-17
    • 2011-08-26
    • 2019-07-17
    • 2013-11-01
    • 2013-11-04
    • 1970-01-01
    • 2015-01-14
    • 2012-03-17
    相关资源
    最近更新 更多