Safari 或 IOS 中视频的 aws-sdk getSignedUrl 不起作用
aws-sdk getSignedUrl for videos in Safari or IOS does not work
我的问题是当我将响应通过管道传输到前端时,Safari(似乎 IOS 上的所有浏览器)都没有显示视频。但是,这些视频显示在所有浏览器的 Android 和 win/linux 桌面上。
请注意,我认为这些视频之前曾在 IOS 和 Safari 中显示过,这可能是最近的错误或对 IOS/Safari 政策的新更改?
我的后端看起来像:
...
const aws = require('aws-sdk');
aws.config.update({
accessKeyId: process.env.ACCESS,
secretAccessKey: process.env.SECRET,
region: process.env.S3_REGION
});
const s3 = new aws.S3();
function getS3Url(filename) {
var params = { Bucket: process.env.BUCKET, Key: filename };
return new Promise((resolve, reject) => {
if (filename) {
s3.getSignedUrl('getObject', params, function(err, url) {
if (err) {
reject(err.message ? err.message : err);
}
resolve(url);
});
} else {
resolve('/none.png');
}
});
}
// Return file
router.get('/file/:filename', (req, res) => {
const { filename = '' } = req.params;
getS3Url(filename).then((url) => {
request(url).pipe(res);
}).catch((err) => {
return res.status(codeToInt(err.code, 404)).send(err.message ? err.message : err);
});
});
我还保存了源标记中使用的媒体类型“video/mp4”。
在我的前端生成的 file-url 将类似于:
src="www.myhost.com/api/file/123" type="video/mp4"
上传到 S3 之前的媒体可以在 Safari 中查看,所以这一定是我用 getSignedUrl 管道响应的方式?
很好的解决方案
解决方案是将 Cloudfront 添加到 AWS。
我不需要实现自己的流媒体服务,而是将签名的 url 返回给前端,这也解决了我在发送 images/videos
时使用我的服务器作为中间人时遇到的另一个问题
“差不多”解
我的问题似乎是 IOS/Safari 只支持流媒体视频
如果客户端是 IOS/Safari:
,我实现了流式响应
function getS3StreamUrl(filename) {
var params = { Bucket: process.env.AWS_BUCKET, Key: filename };
return s3.getObject(params).createReadStream();
}
const isAnnoyingClient = isIOS || isSafari;
if (isAnnoyingClient) {
getS3StreamUrl(filename).pipe(res);
} else {
getS3Url(filename).then((url) => {
request(url).pipe(res);
}).catch((err) => {
return res.status(codeToInt(err.code, 404)).send(err.message ? err.message : err);
});
}
但是现在,我的新问题是 IOS/Safari 中的视频不会循环播放 ,它们只会播放一次..
我的问题是当我将响应通过管道传输到前端时,Safari(似乎 IOS 上的所有浏览器)都没有显示视频。但是,这些视频显示在所有浏览器的 Android 和 win/linux 桌面上。
请注意,我认为这些视频之前曾在 IOS 和 Safari 中显示过,这可能是最近的错误或对 IOS/Safari 政策的新更改?
我的后端看起来像:
...
const aws = require('aws-sdk');
aws.config.update({
accessKeyId: process.env.ACCESS,
secretAccessKey: process.env.SECRET,
region: process.env.S3_REGION
});
const s3 = new aws.S3();
function getS3Url(filename) {
var params = { Bucket: process.env.BUCKET, Key: filename };
return new Promise((resolve, reject) => {
if (filename) {
s3.getSignedUrl('getObject', params, function(err, url) {
if (err) {
reject(err.message ? err.message : err);
}
resolve(url);
});
} else {
resolve('/none.png');
}
});
}
// Return file
router.get('/file/:filename', (req, res) => {
const { filename = '' } = req.params;
getS3Url(filename).then((url) => {
request(url).pipe(res);
}).catch((err) => {
return res.status(codeToInt(err.code, 404)).send(err.message ? err.message : err);
});
});
我还保存了源标记中使用的媒体类型“video/mp4”。 在我的前端生成的 file-url 将类似于: src="www.myhost.com/api/file/123" type="video/mp4"
上传到 S3 之前的媒体可以在 Safari 中查看,所以这一定是我用 getSignedUrl 管道响应的方式?
很好的解决方案
解决方案是将 Cloudfront 添加到 AWS。 我不需要实现自己的流媒体服务,而是将签名的 url 返回给前端,这也解决了我在发送 images/videos
时使用我的服务器作为中间人时遇到的另一个问题“差不多”解
我的问题似乎是 IOS/Safari 只支持流媒体视频
如果客户端是 IOS/Safari:
,我实现了流式响应function getS3StreamUrl(filename) {
var params = { Bucket: process.env.AWS_BUCKET, Key: filename };
return s3.getObject(params).createReadStream();
}
const isAnnoyingClient = isIOS || isSafari;
if (isAnnoyingClient) {
getS3StreamUrl(filename).pipe(res);
} else {
getS3Url(filename).then((url) => {
request(url).pipe(res);
}).catch((err) => {
return res.status(codeToInt(err.code, 404)).send(err.message ? err.message : err);
});
}
但是现在,我的新问题是 IOS/Safari 中的视频不会循环播放 ,它们只会播放一次..