Git Product home page Git Product logo

quasar-ui-qmediaplayer's Introduction

QMediaPlayer (Vue Plugin, UMD and Quasar App Extension)

@quasar/quasar-ui-qmediaplayer @quasar/quasar-app-extension-qmediaplayer GitHub code size in bytes GitHub repo size in bytes

If you are looking for QMediaPlayer v2.+ (with Quasar v2/Vue v3 support) look into the next branch. For v2.+ documentation, go here.

Structure

  • /ui - standalone npm package (go here for more information)
  • /app-extension - Quasar app extension
  • /demo - docs, demo and examples project
  • live demo - live docs, demo and examples

Demo Workflow

If you fork or download this project, make sure you have the Quasar CLI globally installed:

$ npm i -g @quasar/cli

The workflow to build the demo, on a fresh project, is as follows:

$ cd ui
$ yarn
$ yarn build
$ cd ../demo
$ yarn
$ quasar dev

Language Files

We need help translating the language files. They are all currently using English. If you know another language, please PR and help us out.

Completed languages

Example Code

Video example

<q-media-player
  type="video"
  background-color="black"
  :muted="muted"
  radius="1rem"
  :autoplay="true"
  :show-big-play-button="true"
  :sources="video.sources"
  :poster="video.poster"
  :tracks="video.tracks"
  track-language="English"
  @ended="onEnded"
>
  <template v-if="overlay" v-slot:overlay>
    <div>
      <img
        src="quasar-logo.png"
        style="width: 30vw; max-width: 50px; opacity: 0.25;"
      >
    </div>
  </template>
</q-media-player>

and the data...

data () {
  return {
    video: {
      label: 'Tears of Steel',
      poster: 'media/TearsOfSteel/TearsOfSteel.jpeg',
      sources: [
        {
          src: 'http://ftp.nluug.nl/pub/graphics/blender/demo/movies/ToS/tears_of_steel_720p.mov',
          type: 'video/mp4'
        }
      ],
      tracks: [
        {
          src: 'media/TearsOfSteel/TOS-en.vtt',
          kind: 'subtitles',
          srclang: 'en',
          label: 'English'
        },
        {
          src: 'media/TearsOfSteel/TOS-de.vtt',
          kind: 'subtitles',
          srclang: 'de',
          label: 'German'
        },
        {
          src: 'media/TearsOfSteel/TOS-es.vtt',
          kind: 'subtitles',
          srclang: 'es',
          label: 'Spanish'
        },
        {
          src: 'media/TearsOfSteel/TOS-fr-Goofy.vtt',
          kind: 'subtitles',
          srclang: 'fr',
          label: 'French'
        },
        {
          src: 'media/TearsOfSteel/TOS-it.vtt',
          kind: 'subtitles',
          srclang: 'it',
          label: 'Italian'
        },
        {
          src: 'media/TearsOfSteel/TOS-nl.vtt',
          kind: 'subtitles',
          srclang: 'nl',
          label: 'Dutch'
        }
      ]
    }
  }
}

Audio example

audio: {
  sources: [
    {
      src: 'https://raw.githubusercontent.com/quasarframework/quasar-ui-qmediaplayer/dev/demo/public/media/Scott_Holmes_-_04_-_Upbeat_Party.mp3',
      type: 'audio/mp3'
    }
  ]
}

Other

Fullscreen

It is important to note that if you desire fullscreen, then you must add Quasar's AppFullscreen plug-in to your quasar.conf.js. For more information, please refer to the documentation:

// quasar.conf.js

return {
  framework: {
    plugins: [
      'AppFullscreen'
    ]
  }
}

cross-origin

Whether to use CORS for fetching assets.

  1. anonymous - CORS requests for this element will not have the credentials flag set.
  2. use-credentials - CORS requests for this element will have the credentials flag set; this means the request will provide credentials.
  3. null - do not use CORS.

For more detailed information go here.

preload

This enumerated attribute is intended to provide a hint to the browser about what the author thinks will lead to the best user experience. It may have one of the following values:

  1. none: Indicates that the audio should not be preloaded.
  2. metadata: Indicates that only audio metadata (e.g. length) is fetched.
  3. auto: Indicates that the whole audio file can be downloaded, even if the user is not expected to use it.

For more detailed information go here.

networkState

You can capture the networkState with the @networkState event.

  NETWORK_EMPTY = 0
  NETWORK_IDLE = 1
  NETWORK_LOADING = 2
  NETWORK_NO_SOURCE = 3

For more detailed information go here.

MediaError

You can capture the MediaError with the @error event.

  MEDIA_ERR_ABORTED = 1
  MEDIA_ERR_NETWORK = 2
  MEDIA_ERR_DECODE = 3
  MEDIA_ERR_SRC_NOT_SUPPORTED = 4

For more detailed information go here.

iOS

If you want to use the playsinline property with iOS, you will need to add the following to the config.xml for your iOS build:

<preference name="AllowInlineMediaPlayback" value="true" />

Direct Access

If you find you have a need access to the underlying media player, you can set up a ref on QMediaPlayer and access $media directly, even capturing and handling your own events.

  <q-media-player
    ref="myPlayer"
    ...
  />

then

// in code some where
this.$refs.myPlayer.$media

// examples to call native functions directly:
// this.$refs.myPlayer.$media.pause()
// this.$refs.myPlayer.$media.play()

// or via QMediaPlayer
// this.$refs.myPlayer.pause()
// this.$refs.myPlayer.play()

Donate

If you appreciate the work that went into this, please consider donating to Quasar or Jeff.

License

MIT (c) Jeff Galbraith [email protected]

quasar-ui-qmediaplayer's People

Contributors

618457 avatar avhn avatar bichikim avatar birchb avatar borutjures avatar dependabot-preview[bot] avatar fmarquis avatar hawkeye64 avatar kubawolanin avatar lucasfernog avatar luismiguelgilbert avatar mesqueeb avatar mstaack avatar neokazemi avatar nothingismagick avatar patrickmonteiro avatar pdanpdan avatar rstoenescu avatar smolinari avatar someone92 avatar songzhi avatar stefanvanherwijnen avatar thetyrius avatar tobymosque avatar valasek avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

quasar-ui-qmediaplayer's Issues

SSR fails to re-hydrate when initial `type` is 'video'

my code:

<template>
     <q-media-player
          type="video"
          background-color="black"
          :muted="false"
          radius="1rem"
          :autoplay="true"
          :show-big-play-button="true"
          :sources="video.sources"
          :poster="video.poster"
          :tracks="video.tracks"
          track-language="English"
        >
          <template v-if="overlay" v-slot:overlay>
            <div>
              <img
                src="statics/logo.png"
                style="width: 30vw; max-width: 50px; opacity: 0.25;"
              >
            </div>
          </template>
        </q-media-player>
</template>

<style scoped>
</style>

<script>

export default {
  data () {
    return {
      video: [
        {
          label: 'Tears of Steel',
          poster: 'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/BigBuckBunny.jpg',
          sources: [
            {
              src: 'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4',
              type: 'video/mp4'
            }
          ],
          tracks: [
            {
              src: 'statics/media/TearsOfSteel/TOS-en.vtt',
              kind: 'subtitles',
              srclang: 'en',
              label: 'English'
            }
          ]
        }
      ]
    }
  }
}
</script>

browser console:

[Vue warn]: The client-side rendered virtual DOM tree is not matching server-rendered content. This is likely caused by incorrect HTML markup, for example nesting block-level elements inside <p>, or missing <tbody>. Bailing hydration and performing full client-side render.
warn @ vue.runtime.esm.js?2b0e:619
patch @ vue.runtime.esm.js?2b0e:6491
Vue._update @ vue.runtime.esm.js?2b0e:3939
updateComponent @ vue.runtime.esm.js?2b0e:4060
get @ vue.runtime.esm.js?2b0e:4473
Watcher @ vue.runtime.esm.js?2b0e:4462
mountComponent @ vue.runtime.esm.js?2b0e:4067
Vue.$mount @ vue.runtime.esm.js?2b0e:8409
init @ vue.runtime.esm.js?2b0e:3118
hydrate @ vue.runtime.esm.js?2b0e:6372
hydrate @ vue.runtime.esm.js?2b0e:6405
hydrate @ vue.runtime.esm.js?2b0e:6405
patch @ vue.runtime.esm.js?2b0e:6487
Vue._update @ vue.runtime.esm.js?2b0e:3939
updateComponent @ vue.runtime.esm.js?2b0e:4060
get @ vue.runtime.esm.js?2b0e:4473
Watcher @ vue.runtime.esm.js?2b0e:4462
mountComponent @ vue.runtime.esm.js?2b0e:4067
Vue.$mount @ vue.runtime.esm.js?2b0e:8409
init @ vue.runtime.esm.js?2b0e:3118
hydrate @ vue.runtime.esm.js?2b0e:6372
hydrate @ vue.runtime.esm.js?2b0e:6405
hydrate @ vue.runtime.esm.js?2b0e:6405
hydrate @ vue.runtime.esm.js?2b0e:6405
hydrate @ vue.runtime.esm.js?2b0e:6405
patch @ vue.runtime.esm.js?2b0e:6487
Vue._update @ vue.runtime.esm.js?2b0e:3939
updateComponent @ vue.runtime.esm.js?2b0e:4060
get @ vue.runtime.esm.js?2b0e:4473
Watcher @ vue.runtime.esm.js?2b0e:4462
mountComponent @ vue.runtime.esm.js?2b0e:4067
Vue.$mount @ vue.runtime.esm.js?2b0e:8409
init @ vue.runtime.esm.js?2b0e:3118
hydrate @ vue.runtime.esm.js?2b0e:6372
hydrate @ vue.runtime.esm.js?2b0e:6405
hydrate @ vue.runtime.esm.js?2b0e:6405
hydrate @ vue.runtime.esm.js?2b0e:6405
patch @ vue.runtime.esm.js?2b0e:6487
Vue._update @ vue.runtime.esm.js?2b0e:3939
updateComponent @ vue.runtime.esm.js?2b0e:4060
get @ vue.runtime.esm.js?2b0e:4473
Watcher @ vue.runtime.esm.js?2b0e:4462
mountComponent @ vue.runtime.esm.js?2b0e:4067
Vue.$mount @ vue.runtime.esm.js?2b0e:8409
init @ vue.runtime.esm.js?2b0e:3118
hydrate @ vue.runtime.esm.js?2b0e:6372
patch @ vue.runtime.esm.js?2b0e:6487
Vue._update @ vue.runtime.esm.js?2b0e:3939
updateComponent @ vue.runtime.esm.js?2b0e:4060
get @ vue.runtime.esm.js?2b0e:4473
Watcher @ vue.runtime.esm.js?2b0e:4462
mountComponent @ vue.runtime.esm.js?2b0e:4067
Vue.$mount @ vue.runtime.esm.js?2b0e:8409
init @ vue.runtime.esm.js?2b0e:3118
merged @ vue.runtime.esm.js?2b0e:3301
hydrate @ vue.runtime.esm.js?2b0e:6372
hydrate @ vue.runtime.esm.js?2b0e:6405
patch @ vue.runtime.esm.js?2b0e:6487
Vue._update @ vue.runtime.esm.js?2b0e:3939
updateComponent @ vue.runtime.esm.js?2b0e:4060
get @ vue.runtime.esm.js?2b0e:4473
Watcher @ vue.runtime.esm.js?2b0e:4462
mountComponent @ vue.runtime.esm.js?2b0e:4067
Vue.$mount @ vue.runtime.esm.js?2b0e:8409
init @ vue.runtime.esm.js?2b0e:3118
hydrate @ vue.runtime.esm.js?2b0e:6372
patch @ vue.runtime.esm.js?2b0e:6487
Vue._update @ vue.runtime.esm.js?2b0e:3939
updateComponent @ vue.runtime.esm.js?2b0e:4060
get @ vue.runtime.esm.js?2b0e:4473
Watcher @ vue.runtime.esm.js?2b0e:4462
mountComponent @ vue.runtime.esm.js?2b0e:4067
Vue.$mount @ vue.runtime.esm.js?2b0e:8409
(anonymous) @ client-entry.js?2f39:111
(anonymous) @ vue-router.esm.js?8c4f:1898
(anonymous) @ vue-router.esm.js?8c4f:1898
(anonymous) @ vue-router.esm.js?8c4f:2000
step @ vue-router.esm.js?8c4f:1730
step @ vue-router.esm.js?8c4f:1737
step @ vue-router.esm.js?8c4f:1737
runQueue @ vue-router.esm.js?8c4f:1741
(anonymous) @ vue-router.esm.js?8c4f:1995
step @ vue-router.esm.js?8c4f:1730
(anonymous) @ vue-router.esm.js?8c4f:1734
(anonymous) @ vue-router.esm.js?8c4f:1980
(anonymous) @ vue-router.esm.js?8c4f:1773
(anonymous) @ vue-router.esm.js?8c4f:1849
Promise.then (async)
(anonymous) @ vue-router.esm.js?8c4f:1796
(anonymous) @ vue-router.esm.js?8c4f:1817
(anonymous) @ vue-router.esm.js?8c4f:1817
flatMapComponents @ vue-router.esm.js?8c4f:1816
(anonymous) @ vue-router.esm.js?8c4f:1752
iterator @ vue-router.esm.js?8c4f:1959
step @ vue-router.esm.js?8c4f:1733
step @ vue-router.esm.js?8c4f:1737
step @ vue-router.esm.js?8c4f:1737
runQueue @ vue-router.esm.js?8c4f:1741
confirmTransition @ vue-router.esm.js?8c4f:1988
transitionTo @ vue-router.esm.js?8c4f:1890
init @ vue-router.esm.js?8c4f:2541
beforeCreate @ vue-router.esm.js?8c4f:553
invokeWithErrorHandling @ vue.runtime.esm.js?2b0e:1854
callHook @ vue.runtime.esm.js?2b0e:4213
Vue._init @ vue.runtime.esm.js?2b0e:4998
Vue @ vue.runtime.esm.js?2b0e:5079
_callee$ @ client-entry.js?2f39:105
tryCatch @ runtime.js?96cf:45
invoke @ runtime.js?96cf:271
prototype.<computed> @ runtime.js?96cf:97
asyncGeneratorStep @ asyncToGenerator.js?fa84:5
_next @ asyncToGenerator.js?fa84:27
Promise.then (async)
asyncGeneratorStep @ asyncToGenerator.js?fa84:15
_next @ asyncToGenerator.js?fa84:27
Promise.then (async)
asyncGeneratorStep @ asyncToGenerator.js?fa84:15
_next @ asyncToGenerator.js?fa84:27
Promise.then (async)
asyncGeneratorStep @ asyncToGenerator.js?fa84:15
_next @ asyncToGenerator.js?fa84:27
Promise.then (async)
asyncGeneratorStep @ asyncToGenerator.js?fa84:15
_next @ asyncToGenerator.js?fa84:27
Promise.then (async)
asyncGeneratorStep @ asyncToGenerator.js?fa84:15
_next @ asyncToGenerator.js?fa84:27
(anonymous) @ asyncToGenerator.js?fa84:34
F @ _export.js?d13f:36
(anonymous) @ asyncToGenerator.js?fa84:23
_start @ client-entry.js?2f39:70
start @ client-entry.js?2f39:70
(anonymous) @ client-entry.js?2f39:118
./.quasar/client-entry.js @ app.js:929
__webpack_require__ @ app.js:767
fn @ app.js:130
0 @ app.js:8857
__webpack_require__ @ app.js:767
(anonymous) @ app.js:904
(anonymous) @ app.js:907
Show 57 more frames
vue.runtime.esm.js?2b0e:5861 Uncaught (in promise) TypeError: Cannot read property 'toLowerCase' of undefined
    at emptyNodeAt (vue.runtime.esm.js?2b0e:5861)
    at VueComponent.patch [as __patch__] (vue.runtime.esm.js?2b0e:6502)
    at VueComponent.Vue._update (vue.runtime.esm.js?2b0e:3939)
    at VueComponent.updateComponent (vue.runtime.esm.js?2b0e:4060)
    at Watcher.get (vue.runtime.esm.js?2b0e:4473)
    at new Watcher (vue.runtime.esm.js?2b0e:4462)
    at mountComponent (vue.runtime.esm.js?2b0e:4067)
    at VueComponent.Vue.$mount (vue.runtime.esm.js?2b0e:8409)
    at init (vue.runtime.esm.js?2b0e:3118)
    at hydrate (vue.runtime.esm.js?2b0e:6372)

Broken link for the "Sintel" video in Demo project

The second video ("Sintel") appears to have a broken link attached to it. The link that seems to have issue is: https://peach.themazzone.com/durian/movies/sintel-2048-surround.mp4. Tried on Safari (12.1.1), Chrome (74.0.3729.169), Firefox (67.0.1).

Error example from FF: HTTP load failed with status 404. Load of media resource https://peach.themazzone.com/durian/movies/sintel-2048-surround.mp4 failed.

Error example from Chrome: GET https://peach.themazzone.com/durian/movies/sintel-2048-surround.mp4 404 (Not Found)

Error example from Safari: Failed to load resource: the server responded with a status of 404 (Not Found) (pointing to the same media file URL).

The player detects the time track clicks as if I am clicking on the big play button

I have just installed this plugin and whenever I click on the time track to change the current time and the video player pause or unpause the video depending on the current state. If it is playing the video and I click on the time track then the video is paused. If the video is paused and then I click on the time track then the video is unpaused. Basically the player detects the time track clicks as if I am clicking on the big play button.
Here is how I initialize the player:

       <q-media-player
            v-if="video !== null"
            type="video"
            background-color="black"
            :autoplay="false"
            class="video-player"
            :dense="true"
            :show-big-play-button="true"
            :sources="video.sources"
            :poster="video.poster"
            @ended="onEnded"
          >
          </q-media-player>

.......

      this.video = {
          label: stream.Title,
          poster: stream.Poster,
          sources: [
            {
              src: response.data.Url,
              type: 'video/mp4'
            }
          ]
        }

Slots are not detected

qmediaplayer v1.04

When slot is used

<template v-slot:settings-menu>
          <div>
            <!--hide this button-->
           </div>
 </template>

it is ignored and settings-menu, volume and others components are not replaced with custom content.
image

Big Play Button Slot ... class added

If you use the slot for Big Play Button, the template contents still gets wrapped in a div which produces a faint white circle

<div class="q-media--big-button">

Bug: Avoid mutating a prop directly

I have just installed the plugin and whenever I start playing a video I am getting the following error and a few warnings in the chrome console and they are all related to the loading spinner. Even though I am getting this errors the spinner is still appearing on the video player and seems to be working properly.

`vue.runtime.esm.js?2b0e:619 [Vue warn]: Error in callback for watcher "function () { return this._data.$$state }": "Error: [vuex] do not mutate vuex store state outside mutation handlers."

(found in )
warn @ vue.runtime.esm.js?2b0e:619
logError @ vue.runtime.esm.js?2b0e:1884
globalHandleError @ vue.runtime.esm.js?2b0e:1879
handleError @ vue.runtime.esm.js?2b0e:1839
run @ vue.runtime.esm.js?2b0e:4564
update @ vue.runtime.esm.js?2b0e:4536
notify @ vue.runtime.esm.js?2b0e:730
reactiveSetter @ vue.runtime.esm.js?2b0e:1055
(anonymous) @ Index.vue?b484:178
Promise.then (async)
playStream @ Index.vue?b484:176
click @ Index.vue?b5c3:169
invokeWithErrorHandling @ vue.runtime.esm.js?2b0e:1854
invoker @ vue.runtime.esm.js?2b0e:2179
invokeWithErrorHandling @ vue.runtime.esm.js?2b0e:1854
Vue.$emit @ vue.runtime.esm.js?2b0e:3882
Vue. @ backend.js:1140
__onClick @ QItem.js?6ab5:79
invokeWithErrorHandling @ vue.runtime.esm.js?2b0e:1854
invoker @ vue.runtime.esm.js?2b0e:2179
original._wrapper @ vue.runtime.esm.js?2b0e:6911
vue.runtime.esm.js?2b0e:1888 Error: [vuex] do not mutate vuex store state outside mutation handlers.
at assert (vuex.esm.js?2f62:87)
at Vue.store._vm.$watch.deep (vuex.esm.js?2f62:763)
at Watcher.run (vue.runtime.esm.js?2b0e:4562)
at Watcher.update (vue.runtime.esm.js?2b0e:4536)
at Dep.notify (vue.runtime.esm.js?2b0e:730)
at Object.reactiveSetter [as PlayedAt] (vue.runtime.esm.js?2b0e:1055)
at eval (Index.vue?b484:178)
logError @ vue.runtime.esm.js?2b0e:1888
globalHandleError @ vue.runtime.esm.js?2b0e:1879
handleError @ vue.runtime.esm.js?2b0e:1839
run @ vue.runtime.esm.js?2b0e:4564
update @ vue.runtime.esm.js?2b0e:4536
notify @ vue.runtime.esm.js?2b0e:730
reactiveSetter @ vue.runtime.esm.js?2b0e:1055
(anonymous) @ Index.vue?b484:178
Promise.then (async)
playStream @ Index.vue?b484:176
click @ Index.vue?b5c3:169
invokeWithErrorHandling @ vue.runtime.esm.js?2b0e:1854
invoker @ vue.runtime.esm.js?2b0e:2179
invokeWithErrorHandling @ vue.runtime.esm.js?2b0e:1854
Vue.$emit @ vue.runtime.esm.js?2b0e:3882
Vue. @ backend.js:1140
__onClick @ QItem.js?6ab5:79
invokeWithErrorHandling @ vue.runtime.esm.js?2b0e:1854
invoker @ vue.runtime.esm.js?2b0e:2179
original._wrapper @ vue.runtime.esm.js?2b0e:6911
vue.runtime.esm.js?2b0e:619 [Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "spinnerSize"

found in

--->



at src/pages/player/Index.vue
at src/App.vue

warn @ vue.runtime.esm.js?2b0e:619
(anonymous) @ vue.runtime.esm.js?2b0e:4672
reactiveSetter @ vue.runtime.esm.js?2b0e:1045
proxySetter @ vue.runtime.esm.js?2b0e:4625
__renderLoader @ QMediaPlayer.js?1c9f:1177
render @ QMediaPlayer.js?1c9f:1382
Vue._render @ vue.runtime.esm.js?2b0e:3542
updateComponent @ vue.runtime.esm.js?2b0e:4060
get @ vue.runtime.esm.js?2b0e:4473
run @ vue.runtime.esm.js?2b0e:4548
flushSchedulerQueue @ vue.runtime.esm.js?2b0e:4304
(anonymous) @ vue.runtime.esm.js?2b0e:1980
flushCallbacks @ vue.runtime.esm.js?2b0e:1906
Promise.then (async)
timerFunc @ vue.runtime.esm.js?2b0e:1933
nextTick @ vue.runtime.esm.js?2b0e:1990
queueWatcher @ vue.runtime.esm.js?2b0e:4396
update @ vue.runtime.esm.js?2b0e:4538
notify @ vue.runtime.esm.js?2b0e:730
reactiveSetter @ vue.runtime.esm.js?2b0e:1055
(anonymous) @ Index.vue?b484:178
Promise.then (async)
playStream @ Index.vue?b484:176
click @ Index.vue?b5c3:169
invokeWithErrorHandling @ vue.runtime.esm.js?2b0e:1854
invoker @ vue.runtime.esm.js?2b0e:2179
invokeWithErrorHandling @ vue.runtime.esm.js?2b0e:1854
Vue.$emit @ vue.runtime.esm.js?2b0e:3882
Vue. @ backend.js:1140
__onClick @ QItem.js?6ab5:79
invokeWithErrorHandling @ vue.runtime.esm.js?2b0e:1854
invoker @ vue.runtime.esm.js?2b0e:2179
original._wrapper @ vue.runtime.esm.js?2b0e:6911
vue.runtime.esm.js?2b0e:619 [Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "spinnerSize"

found in

--->



at src/pages/player/Index.vue
at src/App.vue
`
I am sorry I don't know a better way to paste the error so here is a screenshot:
image

This is how I have initialized the player:

        <q-media-player
            v-if="video !== null"
            type="video"
            background-color="black"
            :autoplay="false"
            class="video-player"
            :dense="true"
            :show-big-play-button="true"
            :sources="video.sources"
            :poster="video.poster"
            @ended="onEnded"
          >
          </q-media-player>

and in the script section:

    this.video = {
          label: stream.Title,
          poster: stream.Poster,
          sources: [
            {
              src: response.data.Url,
              type: 'video/mp4'
            }
          ]
        }

Settings menu doesn't open while in fullscreen

As we can see in the demo here the settings menu doesn't open while the player is in fullscreen and trying to change it using for example:

<template v-slot:settings-menu> <q-btn label='Test' /> </template>

Doesn't have any effect.

[solved] .m3u8 not working with "type"

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!

[docs] - Vue slots names

Slot has to be named in camelCase format otherwise it is not detected.

<!-- OK -->
<template v-slot:bigPlayButton>
<!-- doesn't work -->
<template v-slot:big-play-button>

[docs] - additional information

Alternative to @mediaPlayer() event which returns a native HTML5 video object can be access to a native object via ref:

this.$refs.qmp.$media

qmediaplayer methods can be accessed e.g.:

this.$refs.qmp.togglePlay();

If you need to use a pause instead of togglePlay you can call native method pause():

this.$refs.qmp.$media.pause();

I promised some time ago to publish a few examples which I miss in the docs but on the other hand every Vue user should be familiar with methods, events and refs (or at least from Quasar docs).

Browser is defaulting to the first source in 'sources', irrespective of support for video type

Stumbled upon the issue when testing in Safari (12.1.1).

I have two video sources, that I'm testing with (pulled from QParallax). When rendering, browser is supposed to look at sources provided (starting from the first one) and resolve to the first one that it supports (MDN Element Video). Given limited support for webm in Safari, it resolves to video/mp4 over video/webm.

However, when implemented using QMediaPlayer, the created HTML video tag seems to implicitly set src attribute to the first source provided (see example below). This seems to force Safari to use this source, whether it supports it or not (bypassing the check for video type support). This resolves in Safari trying to playback webm source, should it be the first one mentioned in the list of sources.

Code that I'm using in my project:

<q-media-player
  type="video"
  :sources="video.sources"
  :poster="video.poster"
  :autoplay="true"
  :show-big-play-button="false"
  :no-controls="true"
  :muted="true"
/>
...
video: {
  poster: 'https://cdn.quasar.dev/img/polina.jpg',
  sources: [
    {
      src: 'https://cdn.quasar.dev/img/polina.webm',
      type: 'video/webm'
    },
    {
      src: 'https://cdn.quasar.dev/img/polina.mp4',
      type: 'video/mp4'
    }
  ]
}

Code that is being generated for my web page is:

<video
  poster="https://cdn.quasar.dev/img/polina.jpg" 
  preload="metadata" 
  class="q-media--player" 
  src="https://cdn.quasar.dev/img/polina.webm"
>
  <p>To view this video please enable JavaScript and/or consider upgrading to a browser that supports HTML5 video.</p>
  <source src="https://cdn.quasar.dev/img/polina.webm" type="video/webm">
  <source src="https://cdn.quasar.dev/img/polina.mp4" type="video/mp4">
</video>

Please notice how video tag gets its src attribute set to webm source.
Firefox (67.0.1) and Chrome (74.0.3729.169) work fine.
Safari, given its limited support for webm, ends up with endless spinner being displayed on top of a crossed-out play button (default apple style), and never resolves to play mp4 source provided.

However, should I change the order of provided sources (so that mp4 goes first, followed by webm) - src attribute changes to mp4 source and Safari plays it just fine (just like in QParallax example mentioned above). But that's an unwanted workaround since I'd like webm to be my primary video source.

QParallax generated HTML code example below:

<div class="q-parallax__media absolute-full">
  <video 
    width="720" 
    height="440" 
    poster="https://cdn.quasar.dev/img/polina.jpg" 
    autoplay="autoplay" 
    loop="loop" 
    muted="muted" 
    style="transform: translate3d(-50%, 115px, 0px);"
>
    <source type="video/webm" src="https://cdn.quasar.dev/img/polina.webm">
    <source type="video/mp4" src="https://cdn.quasar.dev/img/polina.mp4">
  </video>
</div>

I suggest the fix would be to not set src attribute inside video tag at all. I tested creating such code "by hand" and it results in the expected behaviour (Chrome and FF grab the webm source, which is the first one mentioned, and Safari goes to mp4)

[FEAT]: Provide facility to change audio/video source directly

It will be very helpful if the player supported changing of video quality so that the users can choose if they want to play 1080p or 720p video quality. Changing the video quality boils down to changing the video src. I guess I can actually implement this functionality myself by placing buttons somewhere outside of the video player and respond to click events to change the video src. But it would be much better UX if these buttons were embeded inside the player itself so that is more native experience.

TypeError: api.compatibleWith is not a function

Describe the bug

After installing QMediaPlayer, getting an error "TypeError: api.compatibleWith is not a function" error when in SPA mode. Also receiving the same error in SSR mode.

Quasar versions:

Pkg quasar........ v1.5.9
Pkg @quasar/app... v1.4.1

Package.json showing QMediaPlayer version

"devDependencies": {
    "@quasar/app": "^1.4.1",
    "@quasar/quasar-app-extension-qmediaplayer": "^1.0.15",
    "@vue/devtools": "^5.3.3",
    "@vue/eslint-config-prettier": "^4.0.1",
    "babel-eslint": "^10.0.1",
    "eslint": "^5.10.0",
    "eslint-loader": "^2.1.1",
    "eslint-plugin-vue": "^5.0.0"
  },

Stacktrace

Open: ./node_modules/@quasar/quasar-app-extension-qmediaplayer/src/index.js

Starts at line 20:

  conf.css.push('~@quasar/quasar-ui-qmediaplayer/src/index.sass')
}
 
module.exports = function (api) {
  // Quasar compatibility check; you may need
  // hard dependencies, as in a minimum version of the "quasar"
  // package or a minimum version of "@quasar/app" CLI
  api.compatibleWith('quasar', '^1.1.1')
  api.compatibleWith('@quasar/app', '^1.1.0')

To Reproduce
Steps to reproduce the behavior:

  1. Install via quasar ext add @quasar/qmediaplayer
  2. Copy / paste the example code on https://quasarframework.github.io/quasar-ui-qmediaplayer/docs#Example-Code
  3. Start quasar via quasar dev -m ssr or quasar dev
  4. Load the page where the is configured

Expected behavior

The page loads with a video player

Screenshots
If applicable, add screenshots to help explain your problem.

Screen Shot 2019-12-16 at 2 44 21 PM

Desktop (please complete the following information):

  • OS: Mac
  • Browser Chrome
  • Version 79

Smartphone (please complete the following information):

  • Device: iPhone 11 Pro
  • OS: iOS 13.3
  • Browser: Safar
  • Version: iOS 13.3

Additional context

N/A

Icons set for player controls

QMediaPlayer appears to have a dependancy on 'material-icons' which does not appear to be documented.

If you only have 'fontawesome-v5' in the extras section of quasar.config.js then the video controls get messed up because the required icons are no longer available.

Adding 'material-icons' to the extras of quasar.config.js resolves this.

Failed Promise in play()

https://github.com/quasarframework/app-extension-qmediaplayer/blob/a795b1e1030cc58398dde1cfcd209333ab65526e/src/component/QMediaPlayer.js#L494-L509

Sorry to be a pain! if the promise fails then it will still set the playing state to true as you change the state on line 496 and then don't change it back. You need to add a .catch((e) => {}) to the play() promise eg:

this.$media.play().then(() => { 
  this.state.showBigPlayButton = false 
  this.state.playing = true 
  this.__mouseLeaveVideo() 
}).catch((err) => {
  console.error(err)
  this.state.showBigPlayButton = true 
  this.state.playing = false
})

feat: add 'loop' attribute

It'd be nice to have simple :loop="true" property. It's a native property of HTML video tag. Just like it already works with :muted and :autoplay.

Fallback for unsupported video urls

It would be nice to fallback to Qvideo if video source is unsupported, such as in the case of YouTube videos. Right now, QMediaPlayer requires a lot of babysitting via regex and helper functions to switch between QVideo and QMediaPlayer based on the video source.

Basically, if the provided source and type are unsupported, we need to fallback to an alternative player that can handle the stream.

Audio waveforms

Thanks for a great component!

I am using this component for recordings of conversations which sometimes can be quite long. Users have requested a waveform as it helps them see where different parts of the recording / conversation took place, and makes it easier to jump to different spots.

I'm wondering about adding something like this: https://wavesurfer-js.org/example/angular-material/index.html

I'm willing to jump in and attempt the code if it seems like a feasible option and would be a helpful new feature.

Big Play Button colour

Would be nice to have ability to set the colour of the Big Play Button in a similar way to how the colour of the controls can be set.

Example source on main page of docs is incorrect

the example source in the main page of the docs is incorrect ...

it's missing the [videoindex] in the :sources, post, and tracks

It's NOT

      :sources="video.sources"
      :poster="video.poster"

It SHOULD BE

      :sources="video[videoIndex].sources"
      :poster="video[videoIndex].poster"

and videoIndex is missing from he example data section

      videoIndex: 0,

Works fine then

Browser warning for parsing height/width of loader (spinner)

Issue does not seem to affect performance or appearance.
Warning appears in Safari (12.1.1) and Firefox (67.0.1).
Chrome (74.0.3729.169) is fine however.

Warning from FF: Unexpected value 3rem parsing width attribute. Unexpected value 3rem parsing height attribute.

Error from Safari: Error: Invalid value for <svg> attribute height="3rem" Error: Invalid value for <svg> attribute width="3rem"

Both warnings above refer to https://quasarframework.github.io/app-extension-qmediaplayer/js/vendor.f38fe7b9.js and inspecting for the element that the above mentioned height and width are being applied to results in q-spinner element <svg width="3rem" height="3rem" viewBox="25 25 50 50" class="q-spinner q-spinner-mat">...</svg>.

Once again, does not seem to affect performance and appearance, spinner box rendered size is reasonable and computes to 4848px on my screen resolution (25601600px).

Same issue appears in my project. No additional styling is used.
<q-media-player type="video" :sources="video.sources" :poster="video.poster" :autoplay="true" :show-big-play-button="false" :no-controls="true" :muted="true" />

IE11 support

Would be great if IE11 could also be supported.
There is an error objectDOMexception when the page is loaded

  • my project:
<template>
  <div class="column items-center q-pa-md">
    <div class="row" style="height:400px;">
      <q-media-player
        :sources="sources"
        background-color="white"
        type="video">
      </q-media-player>
    </div>
  </div>
</template>
 data() {
      return {
        sources: [
          {
            src: "./data/test.m4v",
            type: "video/m4v"
          },
          {
            src: "./data/test.mp4",
            type: "video/mp4"
          }]
      };
    }

image

Dependabot couldn't find a package.json for this project

Dependabot couldn't find a package.json for this project.

Dependabot requires a package.json to evaluate your project's current JavaScript dependencies. It had expected to find one at the path: /package.json.

If this isn't a JavaScript project, or if it is a library, you may wish to disable updates for it from within Dependabot.

Could we have a poster for an audio

The only audio display could have a poster image/ svg to make it look beautiful
the controls could be switched able/disable
The big button is great for control play/pause

Camera stream ?

Hello,
Thanks for this great quasar extension :)
I would like to know if it's possible to capture camera stream (the recording can be done with recordRTC but I need something to allow the user to show himself).

regards
John

feat: add 'playsinline' attribute

Despite several improvements in the past several years Safari on iOS is still somewhat restrictive in terms of displaying a video to a user. Especially when it comes to playing videos "inline" as opposed to going fullscreen.

For example to make a video autoplay in the background in iOS Safari a developer would need to include playsinline attribute inside a video tag. That's on top of usual autoplay and muted. For this matter, it'd be great to have the ability to set :playsinline: "true" inside q-media-player.

Thank you

Allow Tracks with Sources Type Audio

Probably a limitation of html5 spec, but is there a way to allow a tracks array when the sources type is audio?

I've got a bunch of lyrics.vtt files that accompany my audio files (mp3, flac, etc) but when I add a tracks array (type: 'subtitles') the player breaks.

Is there no way to allow subtitles for audio?

Dependency not found

After upgrading to v12 there is a dependency problem problem when dev or build solution.
image

After reverting back to v11 it is OK.

Reactive prop for audio source

I’m using a q-media component with a :source prop that comes initially as a string that comes from the data() initial data of my component.

When certain events occurs on my component, I’m trying (in a method) to change the source of the q-media components like:

any_method() {
  this.cur_audio_url = "another_audio_url"
}

But the audio source is not changing. Is the source prop of q-media component intended to be reactive? Is that anything I can do to achiev such a thing?

<q-media-player
	  ref="audio_player"
	  type="audio"
	  background-color="black"
	  radius="1rem"
	  track-language="English"
	  :autoplay="true"
	  :source="cur_audio_url"
	  @loaded="audio_loaded"
	  @ready="audio_ready"
>

Improvement proposal: add 'object-fit' attribute

It would be great to have an ability to set object-fit-like property to q-media-player.

Somewhat straightforward way (tested in browser, but not sure of compatibility) would be to set div.q-media style="height: 100%" to make it occupy the entire parent container and then video style="object-fit:{{ property }}.

The idea is to be able to do something like this:

<q-media-player
  :sources="video.sources"
  :object-fit="video.fit"
>
...
video: {
  sources: [...],
  fit: "cover"
}

Using img in BigPlayButton stops click

If you use the slot for BigPlayButton, and click on the IMG rather than the rest of the video, the video will not start, and once the video is playing even though the IMG is not displayed, if you click on it's "position" the click does not stop the video.

Check play() promise

I'm running the code to play audio on load, some browsers don't support this. When play fails the play button still changes to the pause button and users have to click the pause button and then play again to start the stream. Could you use the $media.play().then(-----) to set the playing status so if it fails the play button remains?

IE11 error - since 1.0.6 (incl) expected ')'

Today I updated from v1.0.5 to the latest and realised that since 1.0.6. there is a change blocking whole app to be loaded (tested all newer versions).
image
With v1.0.5 there is video problem but the rest of the app is working. It can be tested directly on demo page in IE11.

Could it be the same problem as described here? I haven't tried to tune babels plugins.

Big Play Button - Size and Style

Would be great if there were alternate sizes for the Big Play Button - maybe use sizes xs, sm, md, lg, xl

And, possibly, ability to make the border thicker and/or to have the circle filled.

And, a further possibility might be other styles of buttons rather than the round circle with the triangle inside - a rectangular YouTube style play button would be good as this would show up more prominently.

I understand that some of these issues can be got around by using the slot to replace the Big Play Button, but using the slot means that you have to start handling all the click events which would not get passed through, so it would be easier for devs if the styling can be done via the QMediaPlayer properties.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.