]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - client/src/assets/player/peertube-videojs-plugin.ts
Improve player progress bar
[github/Chocobozzz/PeerTube.git] / client / src / assets / player / peertube-videojs-plugin.ts
index c99363fb52e65a90b6dfb99f9f0804cf6b76f335..4843e3d8a4ff08c8be1fe5e8c7e8392a1fd61446 100644 (file)
@@ -44,7 +44,21 @@ function bytes (value) {
 
 // videojs typings don't have some method we need
 const videojsUntyped = videojs as any
-const webtorrent = new WebTorrent({ dht: false })
+const webtorrent = new WebTorrent({
+  tracker: {
+    rtcConfig: {
+      iceServers: [
+        {
+          urls: 'stun:stun.stunprotocol.org'
+        },
+        {
+          urls: 'stun:stun.framasoft.org'
+        }
+      ]
+    }
+  },
+  dht: false
+})
 
 const MenuItem: VideoJSComponentInterface = videojsUntyped.getComponent('MenuItem')
 class ResolutionMenuItem extends MenuItem {
@@ -256,7 +270,7 @@ class PeerTubePlugin extends Plugin {
     this.playerElement = options.playerElement
 
     this.player.ready(() => {
-      this.initializePlayer(options)
+      this.initializePlayer()
       this.runTorrentInfoScheduler()
       this.runViewAdd()
     })
@@ -302,17 +316,25 @@ class PeerTubePlugin extends Plugin {
     const previousVideoFile = this.currentVideoFile
     this.currentVideoFile = videoFile
 
-    console.log('Adding ' + videoFile.magnetUri + '.')
-    this.torrent = webtorrent.add(videoFile.magnetUri, torrent => {
-      console.log('Added ' + videoFile.magnetUri + '.')
+    this.addTorrent(this.currentVideoFile.magnetUri, previousVideoFile, done)
+
+    this.trigger('videoFileUpdate')
+  }
+
+  addTorrent (magnetOrTorrentUrl: string, previousVideoFile: VideoFile, done: Function) {
+    console.log('Adding ' + magnetOrTorrentUrl + '.')
+
+    this.torrent = webtorrent.add(magnetOrTorrentUrl, torrent => {
+      console.log('Added ' + magnetOrTorrentUrl + '.')
 
       this.flushVideoFile(previousVideoFile)
 
       const options = { autoplay: true, controls: true }
       renderVideo(torrent.files[0], this.playerElement, options,(err, renderer) => {
+        this.renderer = renderer
+
         if (err) return this.fallbackToHttp()
 
-        this.renderer = renderer
         if (!this.player.paused()) {
           const playPromise = this.player.play()
           if (playPromise !== undefined) return playPromise.then(done)
@@ -325,19 +347,25 @@ class PeerTubePlugin extends Plugin {
     })
 
     this.torrent.on('error', err => this.handleError(err))
+
     this.torrent.on('warning', (err: any) => {
       // We don't support HTTP tracker but we don't care -> we use the web socket tracker
       if (err.message.indexOf('Unsupported tracker protocol') !== -1) return
+
       // Users don't care about issues with WebRTC, but developers do so log it in the console
       if (err.message.indexOf('Ice connection failed') !== -1) {
         console.error(err)
         return
       }
 
+      // Magnet hash is not up to date with the torrent file, add directly the torrent file
+      if (err.message.indexOf('incorrect info hash') !== -1) {
+        console.error('Incorrect info hash detected, falling back to torrent file.')
+        return this.addTorrent(this.torrent['xs'], previousVideoFile, done)
+      }
+
       return this.handleError(err)
     })
-
-    this.trigger('videoFileUpdate')
   }
 
   updateResolution (resolutionId: number) {
@@ -379,7 +407,9 @@ class PeerTubePlugin extends Plugin {
     this.updateVideoFile(undefined, () => this.player.play())
   }
 
-  private initializePlayer (options: PeertubePluginOptions) {
+  private initializePlayer () {
+    this.initSmoothProgressBar()
+
     if (this.autoplay === true) {
       this.updateVideoFile(undefined, () => this.player.play())
     } else {
@@ -463,5 +493,27 @@ class PeerTubePlugin extends Plugin {
   private disableErrorDisplay () {
     this.player.removeClass('vjs-error-display-enabled')
   }
+
+  // Thanks: https://github.com/videojs/video.js/issues/4460#issuecomment-312861657
+  private initSmoothProgressBar () {
+    const SeekBar = videojsUntyped.getComponent('SeekBar')
+    SeekBar.prototype.getPercent = function getPercent () {
+      // Allows for smooth scrubbing, when player can't keep up.
+      // const time = (this.player_.scrubbing()) ?
+      //   this.player_.getCache().currentTime :
+      //   this.player_.currentTime()
+      const time = this.player_.currentTime()
+      const percent = time / this.player_.duration()
+      return percent >= 1 ? 1 : percent
+    }
+    SeekBar.prototype.handleMouseMove = function handleMouseMove (event) {
+      let newTime = this.calculateDistance(event) * this.player_.duration()
+      if (newTime === this.player_.duration()) {
+        newTime = newTime - 0.1
+      }
+      this.player_.currentTime(newTime)
+      this.update()
+    }
+  }
 }
 videojsUntyped.registerPlugin('peertube', PeerTubePlugin)