VideoJS 不播放 mp4 格式的预签名网址

问题描述

我在 vue 应用程序中使用 videojs 在 S3 上播放 mp4 视频文件的预签名 URL。我使用预先签名的 URL 作为 videojs 播放器的来源,但出现错误

无法加载媒体,原因可能是服务器或网络 失败或因为格式不受支持

我的网址如下所示:

https://bucket-name.s3.region.amazonaws.com/object.mp4?AWSAccessKeyId=xxxxxxxxxxxx&Expires=xxxxxxx&Signature=xxxxxx&x-amz-security-token=xxxxxxx

我在 SO 上查看了类似的问题,有人建议将 URL 格式更改为以下格式,但这也不起作用。

https://s3.amazonaws.com/bucket-name/object.mp4?AWSAccessKeyId=xxxxxxxxxxxx&Expires=xxxxxxx&Signature=xxxxxx&x-amz-security-token=xxxxxxx

如果我将上述硬编码 URL 中的任何一个作为其源,则视频播放器会播放视频,但当我将其作为变量时则不会播放。 为什么在使用变量时会改变行为?

<template>
  <div>

        <video-player
          :options="{
            autoplay: false,controls: true,sources: [
              {
                src: `${URL}`,type: 'video/mp4',},],}"
        />
      </div>
    
</template>

<script>

import VideoPlayer from '@/components/VideoPlayer.vue';

var AWS = require('aws-sdk');

var bucketName = 'xxxx';
var s3 = new AWS.S3({
  apiVersion: '2006-03-01',params: { Bucket: bucketName },});

export default {
  components: {
    VideoPlayer,data() {
    return {
      URL: String,};
  },methods: {
    getURL() {
      var self = this;
      let myPromise = new Promise(function (myResolve,myReject) {
        const url = s3.getSignedUrl('getobject',{
          Key: `xxxxx.mp4`,Expires: 3600,});

        myResolve(url);
        myReject('sorry,error');
      });

      myPromise.then(
        function (value) {
          self.URL = value;
        },function (error) {
          console.log(error);
        }
      );
    },mounted() {
    this.getURL();
  },};
</script>

解决方法

问题是 URL 值没有被设置为源,正如@misterben 所提到的。 我进行了以下更改以在方法中设置源。尽管在 Vue 中可能有更好的设置源的方法(除了使用 querySelector)

<video-player
          :options="{
            autoplay: false,controls: true,}"
        />
      </div>

和,

import videojs from 'video.js';
getSignedUrl() {
  // this is because the imported videoPlayer component has class="video-js"
  var player = videojs(document.querySelector('.video-js'));

  var self = this;
  var params = {
    Bucket: 'xxxxx',Key: `xxxxx`,};
  var promise = s3.getSignedUrlPromise('getObject',params);
  promise.then(
    async function (url) {
      self.URL = url;
      await player.src({
        src: url,type: 'video/mp4' /*video type*/,});
    },function (err) {
      console.log(err);
    }
  );
},