提问:使用koa写了一个视频流播放接口,这个接口在pc端浏览器可以播放,但在安卓手机确无法播放,请问这个问题如何解决?

提问:使用koa写了一个视频流播放接口,这个接口在pc端浏览器可以播放,但在安卓手机确无法播放,请问这个问题如何解决?

以下是服务端的接口代码,这段代码是否有问题?

let KoaRouter = require('@koa/router');
let { resolve } = require('path');
let fs = require('fs');

// 访问视频
router.get('/serverVideo', async (ctx) => {
    let { fileName } = ctx.request.query;
    let realFilePath = resolve(__dirname, `../static/videos/${fileName}`);
    let { range } = ctx.request.headers;
    let fileSize = fs.statSync(realFilePath).size;
    ctx.response.set({
        'Content-Type': 'video/mp4',
        'Accept-Ranges': 'bytes',
    });
    if (range) {
        let reg = /bytes=(\d*?)-(\d*?)/ig.exec(range);
        let start = parseInt(reg[1]);
        let end = parseInt(reg[2]);
        end = end ? end : start + 1 * 1024 * 1024;
        end = end <= fileSize - 1 ? end : fileSize - 1;
        ctx.status = 206;
        ctx.response.set({
            'Content-Range': `bytes ${start}-${end}/${fileSize}`,
            'Content-Length': end - start + 1
        });
        let rs = fs.createReadStream(realFilePath, { start, end });
        ctx.body = rs;
    } else {
        ctx.response.set({
            'Content-Length': fileSize
        });
        let rs = fs.createReadStream(realFilePath, { start: 0, end: fileSize - 1 });
        ctx.body = rs;
    }
});

在pc端谷歌浏览器能播放。

img

在安卓手机浏览器确无法播放。

img

这个问题可能是由于安卓手机对于视频流的格式支持不够完善导致的。有些安卓手机可能无法播放MP4格式的视频流,需要使用其他格式的视频流才能正常播放。

另外,你的代码中似乎没有设置跨域的相关头部信息,这可能会导致一些安卓手机无法正常访问该接口。你可以尝试添加以下代码来设置跨域头部信息:

复制代码
ctx.set('Access-Control-Allow-Origin', '*');
ctx.set('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With');
ctx.set('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS');

此外,还需要注意一些安卓手机的视频流播放器可能需要在请求头中添加一些特定的参数,才能正常播放视频流。可以参考一些安卓手机的官方文档或者论坛,查看是否有相关的参数需要设置。

最后,你可以通过在安卓手机端使用一些第三方的视频播放器来尝试播放视频流,以确定是否是安卓手机自带的视频播放器无法播放该视频流。

react-nodejs-koa2视频点播功能实现

可以借鉴下
https://blog.csdn.net/qq_41077776/article/details/127779818

根据您提供的接口代码,目前没有明显的问题。然而,安卓手机无法播放视频可能是由于以下一些常见问题导致的:

视频编码格式:安卓手机对视频编码格式的支持可能与PC浏览器有所不同。请确保您的视频文件采用安卓手机支持的常见视频编码格式,例如H.264编码。

视频文件路径:在代码中,您使用了相对路径来获取视频文件。请确保在安卓手机上可以正确找到视频文件。可以通过在手机浏览器中直接访问视频文件的URL来测试是否可以访问和播放视频。

安卓手机浏览器支持:不同的安卓手机浏览器可能对视频播放有不同的支持。尝试在不同的安卓手机浏览器中测试您的视频播放接口,以确定问题是否与特定浏览器有关。

响应头设置:您在代码中设置了Content-Type为video/mp4,这对于大多数情况下是正确的。但是,某些安卓手机浏览器可能需要更具体的Content-Type设置。您可以尝试设置不同的Content-Type,例如video/mpeg或application/octet-stream,并检查是否对安卓手机浏览器有效。

资源加载速度:在移动设备上,网络连接可能较慢或不稳定,这可能导致视频加载缓慢或无法正常播放。请确保您的视频文件大小适当,以便在移动网络条件下进行流畅播放。

如果上述解决方法仍然无法解决问题,建议您在安卓手机上使用开发者工具(如Chrome开发者工具)进行调试,查看网络请求和响应的详细信息,以确定问题所在。

以下内容引用CHATGPT、有用望采纳:

问题可能出现在视频编码和Android设备的兼容性上。建议尝试将视频编码转换为Android设备支持的格式,例如H.264编码。同时,可以尝试使用HTML5的video标签来播放视频,而不是通过接口返回视频流。以下是使用video标签的示例代码:

<video width="320" height="240" controls>
  <source src="http://yourdomain.com/serverVideo?fileName=yourvideo.mp4" type="video/mp4">
  Your browser does not support the video tag.
</video>

其中,source标签中的src属性为你的视频流接口地址,type属性为视频格式。通过controls属性可以在视频播放器中添加控制条。如果浏览器不支持video标签,将会显示Your browser does not support the video tag.

该回答引用ChatGPT
这个问题可能是由于安卓手机浏览器和PC浏览器对于视频流的处理方式有所不同导致的。在PC浏览器上,视频流可以直接播放,而在安卓手机浏览器上则需要先下载完整的视频文件后才能播放。解决方法可能有以下几种:

1. 使用h5的video标签代替直接返回视频流。在服务端在生成一个html的页面,页面中引用video标签,通过video的src属性指向服务端返回的视频文件地址,这样在安卓手机浏览器上就能正常播放视频文件。

2. 服务端使用webp相关的组件,如webp-blob和webp-converter等,将视频文件转成webp格式后进行返回,这样在安卓手机浏览器上也能够正常播放。

3. 服务端将视频分段进行返回,每个段的大小可以根据网络带宽和视频码率进行调整,这样可以避免安卓手机浏览器上的下载问题,达到流畅播放的效果。

针对第三种方法,可以参考下面的代码,其中涉及到了koa-body、koa-range、range-parse等中间件:

javascript
const KoaRouter = require('@koa/router');
const path = require('path');
const fs = require('fs');
const Koa = require('koa');
const koaBody = require('koa-body');
const koaRange = require('koa-range');
const rangeParser = require('range-parser');

const app = new Koa();
const router = new KoaRouter();

const port = 3000;
const videosPath = path.join(__dirname, '/videos/big-buck-bunny.mp4'); // 视频文件路径
const head = {
'Content-Type': 'video/mp4',
'Accept-Ranges': 'bytes',
};

const stat = fs.statSync(videosPath);
const fileSize = stat.size;

router.get('/video', koaRange, async (ctx) => {
const { headers } = ctx.req;
const { size } = fs.statSync(videosPath);

if (ctx.status === 416) {
ctx.body = 'Requested range not satisfiable
';
return;
}

ctx.set({
...head,
'Content-Length': size,
});

let { start, end } = ctx.query;

start = start ? parseInt(start, 10) : 0;
end = end ? parseInt(end, 10) : size - 1;

const range = headers.range && rangeParser(size, headers.range)[0];

if (range) {
ctx.status = 206;
start = range.start;
end = range.end;
ctx.set({
...head,
'Content-Range': `bytes ${range.start}-${range.end}/${size}`,
'Content-Length': (range.end - range.start) + 1,
});
const stream = fs.createReadStream(videosPath, { start: range.start, end: range.end });
ctx.body = stream;
} else {
console.log('ALL');
ctx.set({
...head,
'Content-Length': size,
});
const stream = fs.createReadStream(videosPath);
ctx.body = stream;
}
});

app.use(koaBody());
app.use(router.routes()).use(router.allowedMethods());
app.listen(port, () => {
console.log(`Server running on port ${port}`);
});


这里使用了koa-body、koa-range、range-parser等中间件,其中koa-range用于处理Range请求头,这可以支持请求特定部分的视频文件,范围为给定的浏览器中的文件大小范围。如果请求范围不合法,返回416状态码。range-parser主要是解析Range请求头。代码中通过createReadStream方法流式返回视频文件内容。

最后如果还有疑问请联系本人。