从《数字海洋》中的视频播放Bug案例谈程序员的态度

发布时间:2023-05-19

一、简介

2019年,我曾经在一家公司担任前端开发工程师,主要负责开发公司官网和数字海洋项目。数字海洋是一个提供在线视频学习课程的平台,用户可以通过该平台学习各种课程,但是在运营过程中,我们遇到了一个非常棘手的Bug:在播放视频的时候,视频会播放几秒钟后自动暂停,刷新页面就可以继续播放,但是仅仅是一时的解决办法,很快又会复现此问题。

二、查找问题

我们经过仔细的分析,一开始怀疑是网络问题,但是通过检测,网络没有问题。紧接着我们又怀疑是服务器问题,通过对服务器进行排查,也未发现服务器问题。我们还怀疑是客户端浏览器的问题,但是验证后也排除了这个问题。看来问题并不好找。 我们当时非常困扰,但是我们并没有放弃,我们开始投入更多的时间去找寻问题的根源。我们检查了代码,尝试了多种解决方案,但均以失败告终。 幸运的是,在我与同事互相交流的过程中,我发现了一个通用现象:Bug出现后,刷新页面就可以正常工作。有了这个线索后,我们逐渐锁定了问题范围。我们发现了是在访问后端接口时出现了问题。

三、修改代码

我们在开始修改代码之前,先从后端入手。我们对后台源代码进行了仔细的检查,逐一排查可能存在的问题,最终锁定了问题出现的位置。在请求视频的URL之后,后端返回的结果中,有一种情况是会返回特定的错误代码。在错误代码出现时,前端客户端会自动停止向服务器发送获取视频流的请求,导致视频暂停。 为了解决这个问题,我们修改了相关代码,使得在遇到该错误代码时,客户端能够自动重新向服务器发送请求,以获取视频流。之后,再运行测试,问题已得到解决。

四、总结

这个Bug的解决,虽然花费了我们很多的时间和精力,但是也使得我们对开发过程中的一些问题有了更深的理解。这个案例中最大的收获就是我们真的牢记:“不要轻易认为你发现了问题的根源,充分探查相关信息,在各个角度下寻找解决方案,从而迈向更高级的程序员!”

五、代码

async function getVideoStream(url, options) {
  let response = await fetch(url, options);
  let reader = response.body.getReader();
  let isRunning = true;
  while (isRunning) {
    let chunk = await reader.read();
    let buffer = chunk.done ? null : chunk.value.buffer;
    if (buffer) {
      // 处理获取到的流
      handleVideoStream(buffer);
    } else {
      // 重新向服务器发送请求,获取视频流
      let responseRe = await fetch(url, options);
      if (responseRe.status !== 200) {
        console.error(`Failed to get video stream : ${responseRe.statusText}`);
        isRunning = false;
      } else {
        reader = responseRe.body.getReader();
      }
    }
  }
}