Vue.js combined with Video.js (MPEG-DASH) is throwing an error: (CODE:4 MEDIA_ERR_SRC_NOT_SUPPORTED)

I am facing an issue with Video.js when using it as a component in vue.js. I receive a .mpd link from a server and I want to display the video from that link. Following the example in the documentation of Video.js and Vue integration.

Every time I call the VideoPlayer for the first time, I encounter an error:

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

If I go back to the previous page and then return to the VideoPlayer, it works fine. However, refreshing the page does not resolve the issue.

P.S: I am utilizing Vuex to fetch all data from the server.

Below 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>

Answer №1

After much trial and error, I have finally discovered the solution to this perplexing issue. The main problem stemmed from the fact that the VideoPlayer component was being rendered before it could retrieve the necessary link from the Store.

Here's how I managed to resolve it: I created a separate component called VueVideoPlayer. Within this component, all requests are made and information is gathered before calling the VideoPlayer.vue component and passing the required 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: It should be noted that in this implementation, I bypassed the use of store/stream.js and directly accessed the services provided by StreamsServices for making API requests.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Issue encountered while adding a value from MongoDB to a list

Encountering an issue when attempting to add an element to an array using a for loop MY CODE router.get('/cart', verifyLogin, async (req, res) => { var products = await userHelpers.getCartProducts(req.session.user._id) console.lo ...

What is the best way to handle subfolders?

I have a question about serving different directories in my dist folder using vercel/serve. Click here to learn more How can I set it up so that localhost/foo will serve the build from the foo directory, and localhost/bar will serve the build from the bar ...

Terser is causing ng build --prod to fail

When I run ng build --prod on my Angular 7 application (which includes a C# app on the BE), I encounter the following error: ERROR in scripts.db02b1660e4ae815041b.js from Terser Unexpected token: keyword (var) [scripts.db02b1660e4ae815041b.js:5,8] It see ...

Encountering an error when attempting to generate a production build after running the npm install command with the

After adding the brotli-webpack-plugin as a devDependency, I encountered an issue when attempting to generate a production build using npm run build (which internally runs next build). The error message displayed was: Error: Cannot find module 'bro ...

Updating jQuery event behaviors based on the value of .html( 'string' )

Visit this link for more information. Feel free to modify the heading if you believe it needs improvement. General I manage a multilingual WordPress website with dynamic menu and navigation controlled through the WordPress admin panel. The multilingual ...

Removing an element from the parent/master array after splicing the copied array

My array setup includes a master array called the parent array. When the page loads, a PHP array encoded in JSON with information about every user on the site is assigned to a JavaScript variable - var all_users = <?php echo $users;?>;. Upon logging ...

Using jQuery and JavaScript: The recursive setTimeout function I created accelerates when the tab is no longer active

I am facing a unique challenge with my jQuery slideshow plugin that I'm currently developing. Although the code is running smoothly, I have observed an issue where if I leave the site open in a tab and browse elsewhere, upon returning to the site (us ...

Tips on creating adaptable images for mobile viewing

My coding conundrum involves the use of two columns - one for an image and the other for a description of that image. However, when viewing my site on mobile devices, the image is cut off at only half its height. Adjusting both columns to col-sm-6 results ...

Despite using Vue and Vuex with Axios asynchronously, the getters are still returning an empty array

I am encountering an issue with getters that are returning the initial state (an empty array). In my component, I have a method called created that sets the axios call result into the state. created() {this.$store.dispatch("SET_STORIES");}, I am using m ...

What could be causing my Node.js website to have trouble locating pages in the public directory?

Embarking on my journey in web development using node.js, I encountered an issue while trying to load a particular page, which led to the following error message in my browser: Cannot GET /public/pages/terms-and-conditions.html The file structure is orga ...

Issue encountered while installing npm via command line

Currently in the process of installing node on my Mac and encountering an error. I downloaded Node from the official website and executed the package, but I am still facing issues. Can anyone advise me on why this error is occurring when I attempt to run ...

JS client-side form validation involves communicating with the server to verify user input

I currently have an HTML form that is being validated on the client side. Below is a snippet of the code: <form id='myForm' onsubmit='return myFormValidation()'> ... </form> Now, I want to incorporate server-side valida ...

Error: Attempting to access the property 'push' of an undefined variable has resulted in an unhandled TypeError

if (Math.random() <= .1) { let orgAdmin = User.find({email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="1234454665324721380c0d">[email protected]</a>'}); or ...

NextJs's React-Quill is unable to effectively highlight syntax using the highlightJS library

I have been working on a NextJs application (blog) that utilizes react-quill as a rich text-editor. As part of my setup, I am making use of the Next custom 'app' feature, where my UserProvider component wraps everything to provide global access t ...

Applying REGEX on input text in React Native

I'm having trouble getting my regex function to work correctly, so I believe there might be an error in my code. Any assistance would be greatly appreciated. Here is the regex function I am using: let validatePlate = (plate) => { var re = /(^[A ...

React encountered an unexpected termination of JSON input during parsing

Upon running npm install, I encountered an error that is shown in the following link: https://i.stack.imgur.com/nVvps.jpg This issue has been causing trouble for me today and I'm unsure of the reason behind it. ...

What is the best way to extract the information from the checkbox in a MUI datatable?

I am struggling to transfer an array with checked values to another table in order to display only those values. How can I achieve this? I am relatively new to using react and I find it challenging to grasp how some of the functions and components work. I ...

Is there a way to ensure that my Delete Entry Button is fully operational?

Excuse my lack of experience in coding. I've been struggling with getting my delete button to function properly on both my webpage and my MySQL database. Right now, when I click the delete button, it just redirects me to a URL ending in /delete withou ...

What is the best method for saving console.log output to a file?

I have a tree structure containing objects: let tree = {id: 1, children: [{id: 2, children: [{id: 3}]}]} My goal is to save all the id values from this tree in a text file, indenting elements with children: 1 2 3 Currently, I am using the following ...

Utilizing Threejs to implement dynamic text labels

Recently, after reading a discussion on stackoverflow, I decided to incorporate labels into my canvas. To achieve this, I created a second scene and camera to overlay the labels on top of the first scene. this.sceneOrtho = new THREE.Scene();//for labels t ...