unash / BarrageRenderer

一个 iOS 上的弹幕渲染库.
https://github.com/unash/BarrageRenderer
MIT License
2.19k stars 451 forks source link

视频中途播放弹幕时间对应错误问题 #64

Closed lichuanliang closed 7 years ago

lichuanliang commented 7 years ago

你好,timeForBarrageRenderer代理中返回了视频的当前时间,我的视频若不是从0秒开始播放的,从五分钟(举例)开始,则无法加载的这个时间点的弹幕,过一段时间后会加载几十秒的弹幕;调试后发现时间有问题,receive:方法异步加载弹幕时,调用了convertDelayTime:方法,让弹幕原有delay时间加上了currentTime,而currentTime接收的是代理里面的,刚开始是nan,之后是五分钟即300秒,所以几十秒的弹幕delay时间会变成三百多秒......我把receive:中[self convertDelayTime:descriptorCopy];注掉了,就可以了。 说的有点乱,不知道看明白没......

unash commented 7 years ago

去掉 [self convertDelayTime:descriptorCopy] 会产生问题,不要去掉。

receive 方法是以当前时间为基准的,所以如果你需要在 「几十秒」的位置播放弹幕, 试试在[快进到300s]之前,调用receive/load方法. 实现上,可以在你的VC里添加一个标志位flag, 初始化 flag=NO, 初始化receive之后,再YES. 然后在代理方法里,判断flag为YES时,再快进300s。

BarrageRenderer 似乎缺少一个和 convertDelayTime 无关的加载弹幕的方法,我之后想办法加上;不会很及时,你先按上述方案实施。

lichuanliang commented 7 years ago

也就是刚开始 flag=NO,代理中返回0;当弹幕全部receive后,代理中再返回正确的视频时间?这样是解决了弹幕receive时delay时间错误的问题。那这样,在我自己发送新弹幕,添加时delay时间需要设置为0,即执行了[self convertDelayTime:descriptorCopy] 后会变成对应的视频时间。 另外, [self convertDelayTime:descriptorCopy]只有在receive时才会执行,并且每个弹幕都只receive一次,所以我认为 [self convertDelayTime:descriptorCopy]内,delay需要加上当前时间是没有必要的。不知道您说的会产生问题是指什么样的问题?可否告知......

lichuanliang commented 7 years ago

补充: 1,我没有快进300秒,而是视频上次播放至了300秒,再次打开时由300秒开始播放,所以我无法在快进到300秒之前调用receive方法;所以如果保留 [self convertDelayTime:descriptorCopy]方法,需要控制的是代理中的返回时间。 2,您说的“BarrageRenderer 似乎缺少一个和 convertDelayTime 无关的加载弹幕的方法,我之后想办法加上”是指在什么需求下?如果是我自己发送的弹幕的话,个人认为还是需要与convertDelayTime关联,因为我发送弹幕屏幕上跑过弹幕后,我可以快退视频,那么再次播放至这个时间时我刚刚发送的弹幕应该还会再次出现。您认为呢?

unash commented 7 years ago

针对这个问题:「另外, [self convertDelayTime:descriptorCopy]只有在receive时才会执行,并且每个弹幕都只receive一次,所以我认为 [self convertDelayTime:descriptorCopy]内,delay需要加上当前时间是没有必要的。不知道您说的会产生问题是指什么样的问题?」

假设 T0 时刻为视频开始位置,T1 为发送弹幕 M(即 receive)时刻,如果在 receive 中不添加 convertDelayTime 方法,那么 M 的 delay 值实际为0. 就会和派发弹幕的地方拿到的时间点不一致。弹幕可能发不出来。另外,在视频后退的时候,时间点也会有问题。

unash commented 7 years ago

针对这个问题:「您说的“BarrageRenderer 似乎缺少一个和 convertDelayTime 无关的加载弹幕的方法,我之后想办法加上”是指在什么需求下?」

开发者使用 load 方法时,未必能够有机会在 timeForBarrageRenderer 调用之前使用。然而 load 方法本质是调用 receive,无一例外地,都添加了一个delay 方法。这对于「在播放过程中拿到批量弹幕并加载」的场景,是不合适的。故需一个不调用 convertDelayTime 的 load 方法。

针对问题:「如果是我自己发送的弹幕的话,个人认为还是需要与convertDelayTime关联,因为我发送弹幕屏幕上跑过弹幕后,我可以快退视频,那么再次播放至这个时间时我刚刚发送的弹幕应该还会再次出现。您认为呢?」

是的。

lichuanliang commented 7 years ago

OK ,以上您三个回复我都明白了,谢谢回复。

unash commented 7 years ago

develop 分支的最新版本,我调整了 load 方法的语义。 对于从网上拉取的delay固定不变的弹幕,任何时候调用 load 都会是正常的。 可以尝试。

https://github.com/unash/BarrageRenderer#load-方法的语义变化