quasarframework / quasar-ui-qmediaplayer

QMediaPlayer for Quasar
https://quasarframework.github.io/quasar-ui-qmediaplayer
MIT License
213 stars 52 forks source link

[solved] .m3u8 not working with "type" #4

Closed HaisojYellams closed 5 years ago

HaisojYellams commented 5 years ago

I wanted to try using the media player component with our VOD service which serves up .mp4.m3u8 files (with a type of application/x-mpegurl), but the spinner just keeps spinning and all video controls remain locked. I was wondering if the current version of the media player is expected to handle this format (and I'm missing a step in the process), if this feature is on the "to-do" list, or if this isn't even on the radar. Thanks!

hawkeye64 commented 5 years ago

What browser and OS? You can also try: application/vnd.apple.mpegurl

HaisojYellams commented 5 years ago

OS: Fedora 29 (5.0.4-200.fc29.x86_64) Browser: Chrome (Version 73.0.3683.86 (Official Build) (64-bit)). I tried using application/vnd.apple.mpegurl, but it didn't seem to change anything.

I also tried on Firefox (66.0.1 (64-bit)), which threw the error

Cannot play media. No decoders for requested formats: application/vnd.apple.mpegurl

I'm assuming there's something on my end I can do to fiddle with Firefox (it's not my default browser, so I haven't spent too much time with it).

hawkeye64 commented 5 years ago

Can you verify this?

3-bar menu => Options => General

Scroll down to "Digital Rights Management (DRM) Content"

Make sure that "Play DRM-controlled content" is checked.

Sorry, I think this is Firefox only for above steps.

hawkeye64 commented 5 years ago

How big is the file? Are you able to send it to me or reference it for me?

HaisojYellams commented 5 years ago

Can you verify this?

I tried doing that with Firefox and it did not change anything.

How big is the file? Are you able to send it to me or reference it for me?

I don't know if I'm allowed to share the video in question, but I can give the following details from the Network tab from Chrome's dev tools:

I am using https://localhost:8080 for testing and am referencing the file via an https://* link. I've tried both with CORS on and off via the Moesif CORS Chrome plugin, if that even makes a difference.

I have been able to get the video pulled in using Videojs (inside of my Vue project), so I know the file exists and is able to be viewed.

hawkeye64 commented 5 years ago

From what I can gather, an m3u8 file is a plain-text file with reference to one or more media (audio or video) files, similar to a playlist.

The HTML5 video player can only play .mp4 or .webm. In addition, .m3u8 is not a 
video file, it is a plain text file used describe where media files are located.

You need to parse the .m3u8 file, get the URLs of the videos and play those with the 
HTML video player.

Ref: https://stackoverflow.com/questions/41246805/play-m3u8-file-in-html5-mobile-application Ref: https://www.lifewire.com/m3u8-file-2621956

HaisojYellams commented 5 years ago

Ah. Not sure how I overlooked that important piece of information.

I guess that brings me back to one of the original questions (and I understand that this might be outside the original scope of the Media Player component): will this component ever be able to handle that parsing for us (like Videojs works "magic" behind the scenes), or should we look for/build our own custom solution? In either case, thank you for your help!

hawkeye64 commented 5 years ago

Yes, we can add it as a feature, but it won't be right away. For now, parse the file and use the results to guide QMediaPlayer. I'll investigate more for handling that type of file. It could really be beneficial for the Audio player as well, as it could handle it like a playlist. Frankly, I never heard of this file until today. :(

HaisojYellams commented 5 years ago

Considering this is still in beta, I definitely did not expect this feature to be added right away. Thanks again for your work on this (and other) Quasar-related projects! It really is an awesome framework.

hawkeye64 commented 5 years ago

Btw, I found this. You may be interested in it. https://github.com/videojs/m3u8-parser

HaisojYellams commented 5 years ago

I literally just pulled that up on my screen! :laughing:

hawkeye64 commented 5 years ago

ref: https://github.com/carlanton/m3u8-parser (A simple HLS playlist parser for Java)

It appears, although not sure yet, that m3u8 files are HSL playlists. If so, HTML5 does not support HSL (live streaming). But QMediaPlayer could with this: https://github.com/video-dev/hls.js/

hawkeye64 commented 5 years ago

Can you replace the right-side of src= below with your path and see if it works?

https://hls-js.netlify.com/demo/?src=https%3A%2F%2Fvideo-dev.github.io%2Fstreams%2Fx36xhzz%2Fx36xhzz.m3u8

HaisojYellams commented 5 years ago

Can you replace the right-side of src= below with your path and see if it works?

I was able that get it to work (once I switched on my Moesif CORS plugin)!

hawkeye64 commented 5 years ago

with the m3u8 file? If so, can you close ticket?

HaisojYellams commented 5 years ago

Yes, with the m3u8 file! Thank you again for your help! :smile:

FadhiliNjagi commented 1 year ago

ref: https://github.com/carlanton/m3u8-parser (A simple HLS playlist parser for Java)

It appears, although not sure yet, that m3u8 files are HSL playlists. If so, HTML5 does not support HSL (live streaming). But QMediaPlayer could with this: https://github.com/video-dev/hls.js/

I'm having trouble integrating Hls.js with QMediaPlayer. I'm using Quasar v2 with webpack. When I do it with HTML video tag, it works:

<template>
  <q-page class="video-page">
    <div class="vp-container">
      <h5>Video test Page</h5>
      <video controls ref="mediaPlayer" class="vp-video" crossorigin="use-credentials">
      </video>
    </div>
  </q-page>
</template>

<script>
import { defineComponent, ref, onMounted, onBeforeUnmount } from 'vue'
import Hls from 'hls.js'

export default defineComponent({
  name: 'VideoPage',
  props: {
    url: {
      type: String,
      default: 'https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8'
    }
  },
  setup (props) {
    const mediaPlayer = ref(null)
    let player = null

    onMounted(() => {
      if (Hls.isSupported()) {
        player = new Hls()
        player.loadSource(props.url)
        console.log('Loaded')
        // console.log(mediaPlayer.value)
        player.attachMedia(mediaPlayer.value)
        player.on(Hls.Events.MANIFEST_PARSED, () => {
          mediaPlayer.value.play()
        })
      }

    onBeforeUnmount(() => {
      if (player) {
        player.destroy()
      }
    })

    return {
      mediaPlayer, player
    }
  }
})
</script>

But when I try with QMediaPlayer it doesn't work

<template>
  <q-page class="video-page">
    <div class="vp-container">
      <h5>Video test Page</h5>
      <q-media-player ref="QMediaPlayer" class="vp-video" crossorigin="use-credentials">
      </q-media-player>
    </div>
  </q-page>
</template>

<script>
import { defineComponent, ref, onMounted, onBeforeUnmount } from 'vue'
import Hls from 'hls.js'

export default defineComponent({
  name: 'VideoPage',
  props: {
    url: {
      type: String,
      default: 'https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8'
    }
  },
  setup (props) {
    const QMediaPlayer = ref(null)
    let player = null

    onMounted(() => {
      if (Hls.isSupported()) {
        player = new Hls()
        player.loadSource(props.url)
        console.log('Loaded')
        // console.log(QMediaPlayer.value.$media)
        player.attachMedia(QMediaPlayer.value.$media)
        player.on(Hls.Events.MANIFEST_PARSED, () => {
          QMediaPlayer.value.play()
        })
      }
    })

    onBeforeUnmount(() => {
      if (player) {
        player.destroy()
      }
    })

    return {
      player, QMediaPlayer
    }
  }
})
</script>