Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

图片无法在VIPlayer播放 #17

Closed
AbySwifter opened this issue May 6, 2019 · 4 comments
Closed

图片无法在VIPlayer播放 #17

AbySwifter opened this issue May 6, 2019 · 4 comments

Comments

@AbySwifter
Copy link
Contributor

AbySwifter commented May 6, 2019

我参考VideoCat的Demo从相册中选择了图片

let resource = PHAssetImageResource.init(asset: asset, duration: CMTime.init(value: 3000, 600))
            guard let task = resource.prepare(progressHandler: progressHandler, completion: { (status, error) in
                if status == .avaliable {
                    resource.selectedTimeRange = CMTimeRange.init(start: CMTime.zero, end: resource.duration)
                    let trackItem: TrackItem = TrackItem(resource: resource)
                    let transition = CrossDissolveTransition()
                    transition.duration = CMTime(value: 900, timescale: 600)
                    trackItem.videoTransition = transition
                    let audioTransition = FadeInOutAudioTransition(duration: CMTime(value: 66150, timescale: 44100))
                    trackItem.audioTransition = audioTransition
                    if resource.isKind(of: ImageResource.self) {
                        trackItem.videoConfiguration.contentMode = .custom
                    } else {
                        trackItem.videoConfiguration.contentMode = .aspectFill
                    }
                    complete(trackItem)
                } else {
                    Log.error("image track status is \(status), check prepare function, error: \(error?.localizedDescription ?? "")")
                    complete(nil)
                }
            })

然后检查了,图片的选择,在 resource.prepare中,Image是存在的,status也是 available的。

public func reloadPlayerItem(_ items: [TrackItem]) -> AVPlayerItem {
        let timeLine = TimeLineManager.current.timeline
        let width = UIScreen.main.bounds.width * UIScreen.main.scale
        let height = width
        timeLine.videoChannel = items
        timeLine.audioChannel = items
        do {
            try Timeline.reloadVideoStartTime(providers: timeLine.videoChannel)
        } catch {
            assert(false, error.localizedDescription)
        }
        timeLine.renderSize = CGSize.init(width: width, height: height)
        let compositonGenerator = CompositionGenerator.init(timeline: timeLine)
        return compositonGenerator.buildPlayerItem()
    }

这是buildItem的方法,视屏和livephoto都没有问题,只有图片无法正常播放,在播放器的时长也不对。

master分支。
xcode 10.2.2
swift 5.0

@AbySwifter
Copy link
Contributor Author

我在buildPlayerItem中断点调试,发现

CompositionGenerator.swift 85行

timeline.videoChannel.enumerated().forEach({ (offset, provider) in
            for index in 0..<provider.numberOfVideoTracks() {
                let trackID: Int32 = getVideoTrackID(for: index) + Int32((offset % 2 + 1) * 1000)
                if let compositionTrack = provider.videoCompositionTrack(for: composition, at: index, preferredTrackID: trackID) {
                    let info = mainVideoTrackInfo.first(where: { $0.track == compositionTrack })
                    if let info = info {
                        info.info.append(provider)
                    } else {
                        let info = TrackInfo.init(track: compositionTrack, info: [provider])
                        mainVideoTrackInfo.append(info)
                    }
                }
            }

这段代码中,provider.numberOfVideoTracks(),的值始终为0.PHAssetImageResource生成的TrackItem。

@AbySwifter
Copy link
Contributor Author

我解决了这个问题。在下面的方法里,添加了对Bundle的定义:

 private static let emptyAsset: AVAsset? = {
        let bundle = Bundle(for: ImageResource.self)
        /// 这里添加的3行代码解决了上述问题
        if let videoURL = bundle.url(forResource: "black_empty", withExtension: "mp4") {
            return AVAsset(url: videoURL)
        }
        if let bundleURL = bundle.resourceURL?.appendingPathComponent("Cabbage.bundle") {
            let resourceBundle = Bundle.init(url: bundleURL)
            if let videoURL = resourceBundle?.url(forResource: "black_empty", withExtension: "mp4") {
                return AVAsset(url: videoURL)
            }
        }
        
        if let url = Bundle.main.url(forResource: "black_empty", withExtension: "mp4") {
            let asset = AVAsset(url: url)
            return asset
        }
        
        return nil
    }()

@vitoziv
Copy link
Contributor

vitoziv commented May 7, 2019

这个修改欢迎提交 pr

@AbySwifter
Copy link
Contributor Author

好的,我会在最近提交PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants