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

关于TrackItem拷贝的问题。About TrackItem Copy. #21

Closed
AbySwifter opened this issue May 31, 2019 · 3 comments
Closed

关于TrackItem拷贝的问题。About TrackItem Copy. #21

AbySwifter opened this issue May 31, 2019 · 3 comments

Comments

@AbySwifter
Copy link
Contributor

当我通过以下方式去填充音频轨道时,我遇到了以下问题:
1、对resouorce实例不进行深拷贝,所有音频资源的selectTimeRange属性总是会与最后一次循环的设置一致。
2、对resource实例进行深拷贝,音频资源的scaledDuration属性,总是为音频长度。
代码如下:

private func caculateMusicTrack(resource: AVAssetTrackResource, duration: CMTime) -> [TrackItem] {
        Log.out(">> Total VIDEO DURATION: \(duration.seconds)")
        Log.out(">> Music File Duration: \(resource.duration.seconds)")
        let numOfLoops = (duration.seconds - currentMusicStartOffset) / resource.duration.seconds
        let numOfLoopsRoundedUp = numOfLoops.rounded(.up)
        var sumPartsTotals = CMTime.zero
        var endS = CMTime.zero
        var result: [TrackItem] = []
        //Audio Trim
        for i in 0..<Int(numOfLoopsRoundedUp) {
            let mResource = resource.copy() as! AVAssetTrackResource
            Log.out(mResource)
            guard let musicAsset = mResource.asset else {
                continue
            }
            //Audio Trim
            let start = CMTimeMake(value: Int64(0.0 * 600), timescale: 600)
            if i == Int(numOfLoopsRoundedUp) - 1 { //is the last chunk of audio
                let lastChunkTimeFrac = numOfLoops.truncatingRemainder(dividingBy: 1) // ex 1.5 will give 0.5
                let lastChunkTimeSecs = musicAsset.duration.seconds * lastChunkTimeFrac //music from 0 to this value
                endS = CMTimeMake(value: Int64((lastChunkTimeSecs-0.05) * 600), timescale: 600)
            } else {
                endS = CMTimeMake(value: Int64(musicAsset.duration.seconds * 600), timescale: 600)
            }
            let timeOffset = CMTime.init(seconds: currentMusicStartOffset, preferredTimescale: 600)
            if i == 0 {
                let startTime = currentMusicStartOffset < 0 ? start - timeOffset : start
                mResource.selectedTimeRange = CMTimeRange.init(start: startTime, end: endS)
            } else {
                mResource.selectedTimeRange = CMTimeRange(start:start , end: endS)
            }
            mResource.selectedTimeRange = CMTimeRange(start:start , end: endS)
            Log.out("selectedStart:\(mResource.selectedTimeRange.start.seconds) - totalPart:\(mResource.selectedTimeRange.end.seconds)")
            let partMyTrackItem = TrackItem(resource: mResource)
            let zeroOffsetTime = CMTimeMultiply(musicAsset.duration, multiplier: Int32(i))
            if i == 0 {
                 partMyTrackItem.startTime = zeroOffsetTime + (currentMusicStartOffset < 0 ? CMTime.zero : timeOffset)
            } else {
                partMyTrackItem.startTime = zeroOffsetTime + timeOffset
            }
            partMyTrackItem.startTime = zeroOffsetTime
            Log.out("start:\(partMyTrackItem.startTime.seconds) - totalPart:\(mResource.scaledDuration.seconds)")
            sumPartsTotals = CMTimeAdd(sumPartsTotals, mResource.scaledDuration)
            result.append(partMyTrackItem)
        }
        return result
    }
@AbySwifter
Copy link
Contributor Author

最终,我通过如下方式解决了问题:
源代码:
AVAssetTrackResource.swift line:96

// MARK: - NSCopying
    override public func copy(with zone: NSZone? = nil) -> Any {
        let resource = super.copy(with: zone) as! AVAssetTrackResource
        resource.asset = asset
        return resource
    }

修改后的代码:

// MARK: - NSCopying
    override public func copy(with zone: NSZone? = nil) -> Any {
        let resource = super.copy(with: zone) as! AVAssetTrackResource
        resource.asset = asset?.copy() as? AVAsset
        resource.scaledDuration = CMTime.invalid
        return resource
    }

@AbySwifter
Copy link
Contributor Author

这里的疑问是关于resource.scaledDuration属性,何时应该将其值赋为 invalid?

@vitoziv
Copy link
Contributor

vitoziv commented May 31, 2019

如果期望视频选择时间就是时间线上的时间那么 resource.scaledDuration 就应该为 invalid。 如果视频选择的时间需要做变速效果就需要设置 scaledDuration。 如果设置了 scaledDuration 之后要记得已经设置了这个,无论之后视频选择了多少视频时间都会变成 scaledDuration,所以要同步修改选择时间和 scaledDuration。看业务需求

@vitoziv vitoziv closed this as completed Jun 27, 2019
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