2

I have problem with Video.js with i use it as component in vue.js. I recieve a .mpd link from a Server and i want to show the video from the link, i did like the example in documentation Video.js and Vue integration.

always the first time i call the VideoPlayer showed an Error:

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

When i go out to the previous page and then to the VideoPlayer again it works. ( also do not works when i refresh the page )

P.s: i use vuex to get all data from Server.

Here is my Code for 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>

and Here is 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>
El-Hani
  • 163
  • 9
  • Have you found an answer to this? I've come across the same problem – MjBVala Jun 20 '20 at 23:38
  • @MjBVala Yes, the problem was that the VideoPlayer will be rendered first and then tries to get the link. What i have done, is to make another component and do all requests inside it, and as long as the link is there, i route to the VideoPlayer component with the link as props. – El-Hani Jun 26 '20 at 10:16

1 Answers1

0

I have found how to solve this problem. The problem was that the VideoPlayer will be rendered first then it tried to get the link from the Store.

How to solve this: you have to try to get the link before the render of VideoPlayer, I made another component VueVideoPlayer. In this component, I do all requests and wait till I get all information, and then call the VideoPlayer.vue component and pass the options as props.

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: here I did not use the store/stream.js, i did direct the request using the StreamsServices.

El-Hani
  • 163
  • 9