aws-samples / amazon-ivs-player-web-sample

This project contains code samples demonstrating how to build, package, and integrate with the Amazon IVS Player Web SDK.
https://docs.aws.amazon.com/ivs/
MIT No Attribution
81 stars 32 forks source link

How to delete ivs-player correctly when using vue for single page application? #30

Open coooo77 opened 3 years ago

coooo77 commented 3 years ago

Describe the bug When using player for SPA(single page application) in vue, leaving and entering the route using player may cause player malfunction.

To Reproduce

  1. clone code

    git clone https://github.com/coooo77/ivs-player.git
    cd ivs-player
  2. Install dependencies and run app

    npm install
    npm run serve
  3. open app in local environment http://localhost:8080/

  4. enter back and forth between Home and About page

Expected behavior ivs player can be delete correctly and works correctly when creating player.

Screenshots

https://user-images.githubusercontent.com/8820762/122716503-e98d1300-d29c-11eb-946f-8e9f6f3d17fd.mp4

Desktop (please complete the following information):

Additional context

  1. Using delete method from ivs-player causes player malfunction, while using dispose method from videojs, it works but accumulating amazon-ivs-wasmworker.min.js and leading to memory leak (as shown above in Screenshots).
  2. if we dont delete player, get waring from videojs and player fails to work:
    VIDEOJS: WARN: Player "videojs-player" is already initialised. Options will not be applied.
    Player is ready to use
tonyjin commented 3 years ago

Thank you for the detailed report! We'll take a look.

alphacentauri82 commented 3 years ago

@coooo77 This is more an issue of appropriately handling the life cycle of a component in Vue.js than an IVS issue per se. Here’s a suggested solution:


<template>
  <div class="playerContainer">
    <video
      ref="videoPlayer"
      id="videojs-player"
      class="video-js vjs-default-skin vjs-16-9 vjs-big-play-centered"
      controls
      playsinline
    />
  </div>
</template>

<script>
import videojs from 'video.js'
import { registerIVSQualityPlugin, registerIVSTech } from 'amazon-ivs-player'

// @ts-ignore
import wasmBinaryPath from 'amazon-ivs-player/dist/assets/amazon-ivs-wasmworker.min.wasm'
import wasmWorkerPath from 'amazon-ivs-player/dist/assets/amazon-ivs-wasmworker.min.js'

export default {
  name: 'IVS-Player',
  data () {
    return {
      player: null,
      videoOptions: {
        autoplay: true
      }
    }
  },
  mounted () {
    // register the tech with videojs
    registerIVSTech(videojs, {
      wasmWorker: this.createAbsolutePath(wasmWorkerPath, document.URL).toString(),
      wasmBinary: this.createAbsolutePath(wasmBinaryPath, document.URL).toString()
    })

    // register the quality plugin
    registerIVSQualityPlugin(videojs)

    // create the player with the appropriate types. We're using @types/video.js VideoJsPlayer, and intersecting our Player and Quality Plugin interface
    this.player = videojs(this.$refs.videoPlayer, this.videoOptions, () => {
      console.log('Player is ready to use!')
      // enable the quality plugin

      const liveStreamUrl =
        'https://fcc3ddae59ed.us-west-2.playback.live-video.net/api/video/v1/us-west-2.893648527354.channel.DmumNckWFTqz.m3u8'

      this.player.src(liveStreamUrl)
    })
    this.player.enableIVSQualityPlugin()

    // listen to IVS specific events
    const events = this.player.getIVSEvents()
    const ivsPlayer = this.player.getIVSPlayer()
    ivsPlayer.addEventListener(events.PlayerState.PLAYING, () => {
      console.log('IVS Player is playing')
    })
  },
  beforeDestroy () {

    if (this.player) {
      this.player.dispose()
    }
  },

  methods: {
    createAbsolutePath (assetPath) {
      console.log(document.URL)
      return new URL(assetPath, document.URL).toString()
    }
  }
}
</script>

<style scoped>
.playerContainer {
  width: 1060px;
  height: 480px;
  margin: auto;
}
</style>

I reproduced your issue and noticed you don’t destroy amazon-ivs & videojs at the same time. In the solution I propose, I embedded it all in a single variable called player.

coooo77 commented 3 years ago

hi @alphacentauri82 i notice that your solution does't using AmazonIVS as techOrder in videoOptions (videojs uses Html5 as default tech), according to Basic VideoJS Tech demo, i add it to your solution and same problem reproduced (memory leak). Is it right way to implement IVS in videojs without setting techOrder?

By the way i get error from Vue using your solution. image

I reproduced your issue and noticed you don’t destroy amazon-ivs & videojs at the same time

wondering that do i have to using both dispose and delete function to destroy ivsplayer?

beforeDestroy () {
    if (this.player) {
      // destroy  videojs
      this.player.dispose()

      // destroy  amazon-ivs
      const player = this.player.getIVSPlayer()
      player.delete()
    }
}
alphacentauri82 commented 3 years ago

Here's a simple example with Vue and Video.js https://github.com/alphacentauri82/ivs-vue You can also see a tutorial i wrote on ionic-vue for reference https://dev.to/superdiana/build-an-amazon-ivs-player-app-with-ionic-vue-1d20

coooo77 commented 3 years ago

https://user-images.githubusercontent.com/8820762/123912412-93f8ea80-d9af-11eb-9686-fad45485a945.mp4

I add vue-router to your code in repo and still got same problem.

Code with problem

pioug commented 3 years ago

Bandlab.com is an SPA too and we had an issue with stopping the player then loading a different stream URL (reusing the same <video> element). We solved it by updating to v1.5.0 💦

tonyjin commented 3 years ago

Thanks for following up @pioug! Does upgrading to v1.5.0 fix your problem @coooo77?

coooo77 commented 3 years ago

Sadly it doesn't fix the problem. I have updated it to the latest version 1.4.x by that time but got same problem. I just using the code from the comment written on 30 Jun and update it to latest version. It reproduces same problem.

We made a SPA with videos in carousel, it keeps creating players while carousel rotates and results in memory leak finally.

mohamadlotfy commented 7 months ago

@tonyjin @coooo77 @alphacentauri82 @pioug Any updates regarding this issue. I'm facing this exact behavior in a nextJs project while trying to use Amazon IVS player with videoJs. Disposing the VideoJs player using dispose() does not delete the amazon-ivs-wasmworker.min.js from the memory.

Screenshot 2024-04-16 at 1 40 11 AM

VideoJs version 8.9.0 Amazon IVS player version 1.26.0

davidskaarup commented 2 months ago

We are also experiencing this issue. Any updates @tonyjin ?