S3 视频未在 iOS 上使用 React 进行流式传输
S3 video not streaming on iOS with React
正如标题所说,我有一些视频保存在 s3 存储桶中。我将我的 nodejs 设置为在我的 React 应用程序上流式传输它。它在除 iOS 以外的所有设备上都能正常工作。我做了一些搜索,但找不到问题。服务器将初始字节请求返回为 206。我检查了 headers 但找不到问题:
这是我的节点:
到达路径后:
if (!range) {
res.status(400).send("returning err!");
return;
}
s3.headObject({
Bucket: process.env.AWS_BUCKET_NAME,
Key: req.params.key
}, function (err, data) {
if (err) {
// an error occurred
console.error(err);
return res.status(500).send("returning err");
}
const videoSize = Number(data.ContentLength);
const CHUNK_SIZE = 10 ** 6; // 1MB
const start = Number(range.replace(/\D/g, ""));
const end = Math.min(start + CHUNK_SIZE, videoSize - 1);
var params = {
Bucket: process.env.AWS_BUCKET_NAME,
Key: req.params.key,
Range: range,
};
var stream = s3.getObject(params).createReadStream();
res.status(206);
res.set('Content-Type', data.ContentType);
res.set('Content-Disposition','inline');
res.set('Accept-Ranges','bytes');
res.set('Accept-Encoding', 'Identity');
res.set('Content-Range', 'bytes ' + start + '-' + end + '/' + videoSize);
res.set('Content-Length', data.ContentLength);
res.set('X-Playback-Session-Id', req.header('X-Playback-Session-Id')); // Part of the attempt to fix
res.set('Connection', 'keep-alive');
res.set('Last-Modified', data.LastModified);
res.set('ETag', data.ETag);
stream.pipe(res);
这是我的前端 React 播放器代码:
<ReactPlayer
ref={player}
// onProgress={onProgress}
playsinline={true}
url={[{ src: source, type: 'video/mp4;' }]} // video location
controls // gives the front end video controls
width='100%'
className='react-player'
height='100%'
allow='autoplay; encrypted-media'
allowFullScreen
// muted={true}
playing={playing}
onPlay={() => setPlaying(true)}
// onPause={() => setPlaying(false)} //part of the attempt to fix
// onSeek={(seek) => playerSeeker(seek)} //part of the attempt to fix
config={{
file: {
attributes: {
controlsList: 'nodownload'
}
}
}}
onContextMenu={e => e.preventDefault()}
onEnded={(e) => onVideoEnded(e)}
onError={(e) => onVideoError(e)}
/>
同样,iOS 上的第一个请求返回 206 成功,但节点总是在开始播放之前结束流。
原来只是
res.set('Content-Length', data.ContentLength);
我需要 return 计算范围的长度,而不是发送视频的完整长度。
正如标题所说,我有一些视频保存在 s3 存储桶中。我将我的 nodejs 设置为在我的 React 应用程序上流式传输它。它在除 iOS 以外的所有设备上都能正常工作。我做了一些搜索,但找不到问题。服务器将初始字节请求返回为 206。我检查了 headers 但找不到问题: 这是我的节点: 到达路径后:
if (!range) {
res.status(400).send("returning err!");
return;
}
s3.headObject({
Bucket: process.env.AWS_BUCKET_NAME,
Key: req.params.key
}, function (err, data) {
if (err) {
// an error occurred
console.error(err);
return res.status(500).send("returning err");
}
const videoSize = Number(data.ContentLength);
const CHUNK_SIZE = 10 ** 6; // 1MB
const start = Number(range.replace(/\D/g, ""));
const end = Math.min(start + CHUNK_SIZE, videoSize - 1);
var params = {
Bucket: process.env.AWS_BUCKET_NAME,
Key: req.params.key,
Range: range,
};
var stream = s3.getObject(params).createReadStream();
res.status(206);
res.set('Content-Type', data.ContentType);
res.set('Content-Disposition','inline');
res.set('Accept-Ranges','bytes');
res.set('Accept-Encoding', 'Identity');
res.set('Content-Range', 'bytes ' + start + '-' + end + '/' + videoSize);
res.set('Content-Length', data.ContentLength);
res.set('X-Playback-Session-Id', req.header('X-Playback-Session-Id')); // Part of the attempt to fix
res.set('Connection', 'keep-alive');
res.set('Last-Modified', data.LastModified);
res.set('ETag', data.ETag);
stream.pipe(res);
这是我的前端 React 播放器代码:
<ReactPlayer
ref={player}
// onProgress={onProgress}
playsinline={true}
url={[{ src: source, type: 'video/mp4;' }]} // video location
controls // gives the front end video controls
width='100%'
className='react-player'
height='100%'
allow='autoplay; encrypted-media'
allowFullScreen
// muted={true}
playing={playing}
onPlay={() => setPlaying(true)}
// onPause={() => setPlaying(false)} //part of the attempt to fix
// onSeek={(seek) => playerSeeker(seek)} //part of the attempt to fix
config={{
file: {
attributes: {
controlsList: 'nodownload'
}
}
}}
onContextMenu={e => e.preventDefault()}
onEnded={(e) => onVideoEnded(e)}
onError={(e) => onVideoError(e)}
/>
同样,iOS 上的第一个请求返回 206 成功,但节点总是在开始播放之前结束流。
原来只是
res.set('Content-Length', data.ContentLength);
我需要 return 计算范围的长度,而不是发送视频的完整长度。