Video.js with Vue.js (MPEG-DASH) ERROR: (CODE:4 MEDIA_ERR_SRC_NOT_SUPPORTED)

Video.js with Vue.js (MPEG-DASH) ERROR: (CODE:4 MEDIA_ERR_SRC_NOT_SUPPORTED)

我在使用 Video.js 时遇到问题,我将其用作 vue.js 中的组件。 我从服务器收到一个 .mpd link,我想显示来自 link 的视频, 我确实喜欢文档 Video.js and Vue integration.

中的示例

我第一次调用 VideoPlayer 时总是显示错误:

VIDEOJS: ERROR: (CODE:4 MEDIA_ERR_SRC_NOT_SUPPORTED) No compatible source was found for this media.

当我转到上一页然后再次转到 VideoPlayer 时,它可以正常工作。 (当我刷新页面时也不起作用)

P.s: 我使用 vuex 从服务器获取所有数据。

这是我的代码 Stream.vue:

<template>
    <div class="container">
        <h1 class="text-center">MediaPlayer for: {{ mediaName }}</h1>
        <video-player :options="videoOptions" />
   </div>
</template>

<script>
import { mapState, mapActions } from "vuex";
import VideoPlayer from "@/components/VideoPlayer.vue";
export default {
    name: "Stream",
    props: ["stream_id", "source"],
    components: {
        VideoPlayer
    },
    created() {
        this.fetchStream(this.stream_id);
    },
    computed: {
        ...mapState("stream", ["stream", "mediaName"]),
        videoOptions() {
            return {
                autoplay: false,
                controls: true,
                sources: [
                    {
                      src:  this.stream.stream_link,
                      type: "application/dash+xml"
                    }
                ],
                poster:"http://placehold.it/380?text=DMAX Video 2"
            };
        }
     },
     methods: {
         ...mapActions("stream", ["fetchStream"])
    }
  };
</script>

<style scoped></style>

这里是VideoPlayer.vue:

<template>
    <div>
        <video ref="videoPlayer" class="video-js"></video>
    </div>
</template>

<script>
  import videojs from "video.js";
  export default {
    name: "VideoPlayer",
    props: {
      options: {
        type: Object,
        default() {
          return {};
        }
      }
    },
    data() {
      return {
        player: null
      };
    },
    mounted() {
      this.player = videojs(
              this.$refs.videoPlayer,
              this.options,
              function onPlayerReady() {
                console.log("onPlayerReady", this);
              }
      );
    },
    beforeDestroy() {
      if (this.player) {
        this.player.dispose();
      }
    }
  };
</script>

我找到了解决这个问题的方法。 问题是 VideoPlayer 将首先呈现,然后它尝试从商店获取 link。

如何解决: 你必须尝试在VideoPlayer渲染之前获取link,我制作了另一个组件VueVideoPlayer。在此组件中,我执行所有请求并等待获取所有信息,然后调用 VideoPlayer.vue 组件并将选项作为道具传递。

VueVideoPlayer.vue

<template>
  <div>
      <div v-if="loading">
      <div class="text-center">
        <div
           class="spinner-border m-5 spinner-border-lg"
           style="width: 3rem; height: 3rem;  border-top-color: rgb(136, 255, 24);
                                                              border-left-color: 
                                                               rgb(136, 255, 24);
                                                              border-right-color: 
                                                              rgb(136, 255, 24);
                                                              border-bottom-color: 
                                                              rgb(97, 97, 97); "
            role="status"
        >
          <span class="sr-only">Loading...</span>
         </div>
       </div>
     </div>
    <div v-else>
      <video-player :options="videoOptions" />
    </div>
   </div>
 </template>

 <script>
 import VideoPlayer from "@/components/VideoPlayer.vue";
 import StreamsServices from "../services/StreamsServices";
 import NProgress from "nprogress";
 import CookieService from "../services/CookieSerice";


 export default {
   name: "VueVideoPlayer",
   components: {
     VideoPlayer
   },
   data() {
     return {
      player: null,
      stream_link: "",
      loading: false
    };
  },
  created() {
    this.loading = true;
    NProgress.start();
     StreamsServices.getStream(this.stream_id, this.settings)
      .then(response => {
        this.stream_link = response.data.stream_link;
      })
      .finally(() => {
        NProgress.done();
        this.loading = false;
        this.keepAlive();
        this.interval = setInterval(this.keepAlive, 20000);
      });
  },
  props: ["stream_id", "settings"],
  computed: {
    videoOptions() {
      return {
        autoplay: false,
        controls: true,
        sources: [
          {
            src: this.stream_link,
            type: "application/dash+xml"
          }
        ],
        poster: "http://placehold.it/380?text=DMAX Video 2"
      };
    }
  },
  methods: {
    keepAlive() {
      CookieService.getToken().then(token => {
        StreamsServices.postKeepAlive({
          token: token,
          audiopreset: this.settings.videoPresetId,
          videopreset: this.settings.audioPresetId,
          transcodedVideoUri: this.stream_link
        }).then(() => {});
      });
    }
  }
};
</script>

PS:这里我没有使用store/stream.js,我直接使用StreamsServices请求。