Я пытаюсь передать видео в формате mp4 из своего ведра AWS S3 на веб-страницу, используя response.js для клиента и node.js в качестве сервера. Однако я немного новичок в обоих из них. Во внешнем интерфейсе в одном из моих компонентов реакции в рендере есть следующее (некоторый код в возврате опущен для актуальности):
render() {
const { classes } = this.props;
return(
<video id = "video" width = "1280" height = "720" controls>
Your browser does not support the video tag.
<source src = {this.state.videoNow} type='video/mp4' />
</video>
);
}
В том же классе у меня есть функция componentDidMount ():
componentDidMount() {
fetch("/api/annotate", {
headers: {'Authorization': 'Bearer ' + localStorage.getItem('token')}
})
.then(res => {
this.setState({
videoNow: res
});
,(error) => {
console.info(error)
})
}
В моем файле server.js у меня есть следующее:
app.get('/api/annotate',
(req, res) => {
var s3 = new AWS.S3();
const mimetype = 'video/mp4';
const file = '<video source in bucket>';
const cache = 0;
console.info('const mimetype, file, and cache declared');
s3.listObjectsV2({Bucket: <name of bucket>, MaxKeys: 1, Prefix: file}, function(err, data) {
if (err) {
return res.sendStatus(404);
}
console.info('made request to s3 to list objects');
if ((req != null) && (req.headers.range != null)) {
var range = req.headers.range;
var bytes = range.replace(/bytes=/, '').split('-');
var start = parseInt(bytes[0], 10);
var total = data.Contents[0].Size;
var end = bytes[1] ? parseInt(bytes[1], 10) : total - 1;
var chunksize = (end - start) + 1;
console.info('declared range, bytes, start, total, end, chunksize vars');
res.writeHead(206, {
'Content-Range' : 'bytes ' + start + '-' + end + '/' + total,
'Accept-Ranges' : 'bytes',
'Content-Length' : chunksize,
'Last-Modified' : data.Contents[0].LastModified,
'Content-Type' : mimetype
});
console.info('wrote header');
s3.getObject({Bucket: <name of bucket>, Key: file, Range: range}).createReadStream().pipe(res);
console.info('got object from s3 and created readstream');
}
else
{
res.writeHead(200,
{
'Cache-Control' : 'max-age=' + cache + ', private',
'Content-Length': data.Contents[0].Size,
'Last-Modified' : data.Contents[0].LastModified,
'Content-Type' : mimetype
});
s3.getObject({Bucket: <name of bucket>, Key: file}).createReadStream().pipe(res);
console.info('fell into else statement, wrote header');
}
});
});
Когда я запускаю этот код, я замечаю, что оператор else в моем файле server.js всегда запускается один раз, и больше ничего не происходит. Видео не загружается, и консоль сообщает, что видео не удалось найти. Если я изменю источник видео в моем реагирующем компоненте на src = '/ api / annotate', видео загрузится отлично. Проблема в том, что я пытаюсь добавить аутентификацию, и это работает, только если у меня есть componentDidMount. Я много дней искал, как решить эту проблему, и не нашел многого. Еще раз, я новичок во всем этом. Любой совет будет очень признателен !!!





Мне кажется, вы пытаетесь установить настоящие видеоданные в свой источник. Это вряд ли сработает. Кроме того, я не уверен, почему вы обслуживаете файл с S3 через свой сервер node.js.
Это кажется гораздо лучшим решением, если ваш node.js просто gсоздал предварительно подписанный URL и вернет его, который затем можно легко установить в качестве источника. Они способствуют тому, что все данные также не должны передаваться через ваше приложение для заметок.
Еще лучше было бы разместить Cloudfront перед вашей корзиной S3, а затем использовать тот же создание предварительно подписанных URL-адресов для этого.
Не знаю, как помочь вам с этим, но в ваших функциях обещания, когда вы извлекаете данные, у вас есть
,вместо..