svga / SVGAPlayer-iOS

Similar to Lottie. Render After Effects / Animate CC (Flash) animations natively on Android and iOS, Web. 使用 SVGAPlayer 在 Android、iOS、Web中播放 After Effects / Animate CC (Flash) 动画。
http://svga.io
Apache License 2.0
1.08k stars 293 forks source link

声音可能无法播放的问题 #114

Closed liliangde closed 4 years ago

liliangde commented 4 years ago

带声音的svga可能无法播放问题。

查看了下源码,在播放声音时有一个判断是否play的方法如下:

if (self.forwardAnimating && self.audioLayers.count > 0) {
        for (SVGAAudioLayer *layer in self.audioLayers) {
            if (layer.audioItem.startFrame == self.currentFrame) {
                [layer.audioPlayer setCurrentTime:(NSTimeInterval)(layer.audioItem.startTime / 1000)];
                [layer.audioPlayer play];
            }
            else if (layer.audioItem.endFrame <= self.currentFrame) {
                [layer.audioPlayer stop];
            }
        }
    }

问题就出现在第一个if: self.audioLayers.count > 0的判断。audioLayers这个数组是在draw方法里面添加元素的,但是这个draw方法是在setVideoItem:中在主线程调用的。如果draw方法还没有调用的情况下就触发了定时器的方法,就会导致第一次进入update方法时audioLayers数组为空。在下一次执行定时器方法时,此时的currentFrame已经不等于layer.audioItem.startFrame了(startFrame等于0),故就不会执行[layer.audioPlayer play]这个方法。导致声音无法播放。可以在主队列中调用startAnimation方法暂时解决这个问题。但还是希望作者可以在sdk中处理这个问题。建议将startAnimation方法也放到主队列执行。

PonyCui commented 4 years ago

I've confirm this issue.

thyonline commented 4 years ago

并不需要从主线程执行去修复那个问题,` 我是这么做的 在 SVGAPlayer.h 文件中, 增加了一个对外的方法

// 不使用set方法进行赋值, 使用接口赋值 // videoItem 视频实体 // completeBlock 为 Draw() 执行完成的回调

// SVGAPlayer.h

- (void)initilizeVideoItem: (SVGAVideoEntity *)videoItem completeHandle: (SVGAPlayerDidFinishedDrawOptions)completeBlock;

// SVGAPlayer.m

-  (void)initilizeVideoItem:(SVGAVideoEntity *)videoItem completeHandle:(SVGAPlayerDidFinishedDrawOptions)completeBlock {
    _videoItem = videoItem;
    _currentRange = NSMakeRange(0, videoItem.frames);
    _reversing = NO;
    _currentFrame = 0;
    _loopCount = 0;
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
       [self clear];
       [self draw];
       completeBlock();
    }];
}

动画并未执行, 但是视频实体帧数 +1过了 layer.audioItem.startFrame =0 self.currentFrame = 1 因为时间紧张, 所以我暂时对 startFrame 手动+1 进行补偿

if (!self.audioPlaying && (layer.audioItem.startFrame + 1) >= self.currentFrame) {

}

修改后, 目前暂无问题, 希望有所帮助

yangqingren commented 4 years ago

fixed in 2.5.4