]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - client/src/assets/player/p2p-media-loader/segment-validator.ts
Fix console error when watching a video
[github/Chocobozzz/PeerTube.git] / client / src / assets / player / p2p-media-loader / segment-validator.ts
index 0614f73d2dc79bb70715cc245342a78516c27665..4a0caec5e621cbb469978665513e7f513c2d5057 100644 (file)
@@ -1,27 +1,35 @@
+import { wait } from '@root-helpers/utils'
 import { Segment } from 'p2p-media-loader-core'
 import { basename } from 'path'
 
 type SegmentsJSON = { [filename: string]: string | { [byterange: string]: string } }
 
-function segmentValidatorFactory (segmentsSha256Url: string) {
+const maxRetries = 3
+
+function segmentValidatorFactory (segmentsSha256Url: string, isLive: boolean) {
   let segmentsJSON = fetchSha256Segments(segmentsSha256Url)
   const regex = /bytes=(\d+)-(\d+)/
 
-  return async function segmentValidator (segment: Segment, canRefetchSegmentHashes = true) {
+  return async function segmentValidator (segment: Segment, _method: string, _peerId: string, retry = 1) {
+    // Wait for hash generation from the server
+    if (isLive) await wait(1000)
+
     const filename = basename(segment.url)
 
     const segmentValue = (await segmentsJSON)[filename]
 
-    if (!segmentValue && !canRefetchSegmentHashes) {
+    if (!segmentValue && retry > maxRetries) {
       throw new Error(`Unknown segment name ${filename} in segment validator`)
     }
 
     if (!segmentValue) {
-      console.log('Refetching sha segments.')
+      console.log('Refetching sha segments for %s.', filename)
+
+      await wait(1000)
 
-      // Refetch
       segmentsJSON = fetchSha256Segments(segmentsSha256Url)
-      segmentValidator(segment, false)
+      await segmentValidator(segment, _method, _peerId, retry + 1)
+
       return
     }
 
@@ -41,7 +49,7 @@ function segmentValidatorFactory (segmentsSha256Url: string) {
       throw new Error(`Unknown segment name ${filename}/${range} in segment validator`)
     }
 
-    const calculatedSha = bufferToEx(await sha256(segment.data))
+    const calculatedSha = await sha256Hex(segment.data)
     if (calculatedSha !== hashShouldBe) {
       throw new Error(
         `Hashes does not correspond for segment ${filename}/${range}` +
@@ -68,14 +76,21 @@ function fetchSha256Segments (url: string) {
     })
 }
 
-function sha256 (data?: ArrayBuffer) {
+async function sha256Hex (data?: ArrayBuffer) {
   if (!data) return undefined
 
-  return window.crypto.subtle.digest('SHA-256', data)
+  if (window.crypto.subtle) {
+    return window.crypto.subtle.digest('SHA-256', data)
+      .then(data => bufferToHex(data))
+  }
+
+  // Fallback for non HTTPS context
+  const shaModule = await import('sha.js')
+  return new shaModule.sha256().update(Buffer.from(data)).digest('hex')
 }
 
 // Thanks: https://stackoverflow.com/a/53307879
-function bufferToEx (buffer?: ArrayBuffer) {
+function bufferToHex (buffer?: ArrayBuffer) {
   if (!buffer) return ''
 
   let s = ''