aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/assets/player/video-renderer.ts
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/assets/player/video-renderer.ts')
-rw-r--r--client/src/assets/player/video-renderer.ts55
1 files changed, 37 insertions, 18 deletions
diff --git a/client/src/assets/player/video-renderer.ts b/client/src/assets/player/video-renderer.ts
index bda40b11d..174676ffa 100644
--- a/client/src/assets/player/video-renderer.ts
+++ b/client/src/assets/player/video-renderer.ts
@@ -1,8 +1,8 @@
1// Thanks: https://github.com/feross/render-media 1// Thanks: https://github.com/feross/render-media
2// TODO: use render-media once https://github.com/feross/render-media/issues/32 is fixed 2// TODO: use render-media once https://github.com/feross/render-media/issues/32 is fixed
3 3
4import { extname } from 'path'
5import * as MediaElementWrapper from 'mediasource' 4import * as MediaElementWrapper from 'mediasource'
5import { extname } from 'path'
6import * as videostream from 'videostream' 6import * as videostream from 'videostream'
7 7
8const VIDEOSTREAM_EXTS = [ 8const VIDEOSTREAM_EXTS = [
@@ -27,7 +27,7 @@ function renderVideo (
27 return renderMedia(file, elem, opts, callback) 27 return renderMedia(file, elem, opts, callback)
28} 28}
29 29
30function renderMedia (file, elem: HTMLVideoElement, opts: RenderMediaOptions, callback: (err: Error, renderer: any) => void) { 30function renderMedia (file, elem: HTMLVideoElement, opts: RenderMediaOptions, callback: (err: Error, renderer?: any) => void) {
31 const extension = extname(file.name).toLowerCase() 31 const extension = extname(file.name).toLowerCase()
32 let preparedElem = undefined 32 let preparedElem = undefined
33 let currentTime = 0 33 let currentTime = 0
@@ -41,18 +41,33 @@ function renderMedia (file, elem: HTMLVideoElement, opts: RenderMediaOptions, ca
41 41
42 function useVideostream () { 42 function useVideostream () {
43 prepareElem() 43 prepareElem()
44 preparedElem.addEventListener('error', fallbackToMediaSource) 44 preparedElem.addEventListener('error', function onError () {
45 preparedElem.removeEventListener('error', onError)
46
47 return fallbackToMediaSource()
48 })
45 preparedElem.addEventListener('loadstart', onLoadStart) 49 preparedElem.addEventListener('loadstart', onLoadStart)
46 return videostream(file, preparedElem) 50 return videostream(file, preparedElem)
47 } 51 }
48 52
49 function useMediaSource () { 53 function useMediaSource (useVP9 = false) {
54 const codecs = getCodec(file.name, useVP9)
55
50 prepareElem() 56 prepareElem()
51 preparedElem.addEventListener('error', callback) 57 preparedElem.addEventListener('error', function onError(err) {
58 // Try with vp9 before returning an error
59 if (codecs.indexOf('vp8') !== -1) {
60 preparedElem.removeEventListener('error', onError)
61
62 return fallbackToMediaSource(true)
63 }
64
65 return callback(err)
66 })
52 preparedElem.addEventListener('loadstart', onLoadStart) 67 preparedElem.addEventListener('loadstart', onLoadStart)
53 68
54 const wrapper = new MediaElementWrapper(preparedElem) 69 const wrapper = new MediaElementWrapper(preparedElem)
55 const writable = wrapper.createWriteStream(getCodec(file.name)) 70 const writable = wrapper.createWriteStream(codecs)
56 file.createReadStream().pipe(writable) 71 file.createReadStream().pipe(writable)
57 72
58 if (currentTime) preparedElem.currentTime = currentTime 73 if (currentTime) preparedElem.currentTime = currentTime
@@ -60,10 +75,11 @@ function renderMedia (file, elem: HTMLVideoElement, opts: RenderMediaOptions, ca
60 return wrapper 75 return wrapper
61 } 76 }
62 77
63 function fallbackToMediaSource () { 78 function fallbackToMediaSource (useVP9 = false) {
64 preparedElem.removeEventListener('error', fallbackToMediaSource) 79 if (useVP9 === true) console.log('Falling back to media source with VP9 enabled.')
80 else console.log('Falling back to media source..')
65 81
66 useMediaSource() 82 useMediaSource(useVP9)
67 } 83 }
68 84
69 function prepareElem () { 85 function prepareElem () {
@@ -96,16 +112,19 @@ function validateFile (file) {
96 } 112 }
97} 113}
98 114
99function getCodec (name: string) { 115function getCodec (name: string, useVP9 = false) {
100 const ext = extname(name).toLowerCase() 116 const ext = extname(name).toLowerCase()
101 return { 117 if (ext === '.mp4') {
102 '.m4a': 'audio/mp4; codecs="mp4a.40.5"', 118 return 'video/mp4; codecs="avc1.640029, mp4a.40.5"'
103 '.m4v': 'video/mp4; codecs="avc1.640029, mp4a.40.5"', 119 }
104 '.mkv': 'video/webm; codecs="avc1.640029, mp4a.40.5"', 120
105 '.mp3': 'audio/mpeg', 121 if (ext === '.webm') {
106 '.mp4': 'video/mp4; codecs="avc1.640029, mp4a.40.5"', 122 if (useVP9 === true) return 'video/webm; codecs="vp9, opus"'
107 '.webm': 'video/webm; codecs="opus, vorbis, vp8"' 123
108 }[ext] 124 return 'video/webm; codecs="vp8, vorbis"'
125 }
126
127 return undefined
109} 128}
110 129
111export { 130export {