Merge branch 'michael/player-change' into 'v3'
Remove video.js and replace with dashjs/hls.js/HTML5 video player See merge request videostreaming/fcast!2
3
.gitignore
vendored
|
@ -1 +1,4 @@
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
|
# Ignore VSCode user project settings
|
||||||
|
.vscode
|
||||||
|
|
BIN
receivers/electron/assets/fonts/inter/InterVariable.woff2
Normal file
7
receivers/electron/assets/fonts/inter/inter.css
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
@font-face {
|
||||||
|
font-family: InterVariable;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 100 900;
|
||||||
|
font-display: swap;
|
||||||
|
src: url("InterVariable.woff2") format("woff2");
|
||||||
|
}
|
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 7.9 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
20
receivers/electron/assets/icons/player/icon.svg
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<svg
|
||||||
|
width="1024"
|
||||||
|
height="1024"
|
||||||
|
viewBox="0 0 270.93333 270.93333"
|
||||||
|
xmlns="http://www.w3.org/2000/svg" >
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
clip-rule="evenodd"
|
||||||
|
d="m 136.60506,270.93333 c 23.09465,0 36.42801,-16.30932 36.42801,-36.42806 0,-20.1186 -14.29179,-36.42801 -36.42801,-36.42801 -22.13611,0 -36.428,16.30941 -36.428,36.42801 0,20.11874 13.33325,36.42806 36.428,36.42806 z m -9.48928,-47.06983 -1.15136,1.15135 c -4.47359,4.47359 -6.71038,6.71055 -6.71038,9.48999 0,2.77969 2.23679,5.01636 6.71038,9.48995 l 1.15136,1.15136 c 4.47359,4.4736 6.71054,6.71048 9.48997,6.71048 2.77943,0 5.0164,-2.23688 9.49001,-6.71048 l 1.15135,-1.15136 c 4.47357,-4.47359 6.71045,-6.71026 6.71045,-9.48995 0,-2.77944 -2.23688,-5.0164 -6.71045,-9.48999 l -1.15135,-1.15135 c -4.47361,-4.4735 -6.71058,-6.71039 -9.49001,-6.71039 -2.77943,0 -5.01638,2.23689 -9.48997,6.71039 z"
|
||||||
|
fill="#ffffff" />
|
||||||
|
<path
|
||||||
|
d="M 246.30301,0 H 24.630317 C 11.083288,0 0,11.526214 0,25.613462 v 25.613455 c 0,7.043877 5.5418993,12.80673 12.315158,12.80673 6.773263,0 12.31516,-5.762853 12.31516,-12.80673 V 38.420189 c 0,-7.043371 5.541898,-12.806727 12.31512,-12.806727 H 233.98788 c 6.77327,0 12.31513,5.763356 12.31513,12.806727 V 192.10153 c 0,7.04389 -5.54186,12.80727 -12.31513,12.80727 h -39.70302 c -6.77323,0 -12.31513,5.76285 -12.31513,12.80671 0,7.04387 5.5419,12.80566 12.31513,12.80566 h 52.01815 c 13.54652,0 24.63032,-11.52515 24.63032,-25.61237 V 25.613462 C 270.93333,11.526214 259.84953,0 246.30301,0 Z"
|
||||||
|
fill="#ffffff" />
|
||||||
|
<path
|
||||||
|
d="M 24.630317,0 H 246.30301 c 13.54703,0 24.63032,11.526214 24.63032,25.613462 v 25.613455 c 0,7.043877 -5.54189,12.80673 -12.31515,12.80673 -6.77327,0 -12.31517,-5.762853 -12.31517,-12.80673 V 38.420189 c 0,-7.043371 -5.54189,-12.806727 -12.31512,-12.806727 H 36.945449 c -6.773265,0 -12.315132,5.763356 -12.315132,12.806727 V 192.10153 c 0,7.04389 5.541867,12.80727 12.315132,12.80727 h 39.703028 c 6.773235,0 12.315162,5.76285 12.315162,12.80671 0,7.04387 -5.541927,12.80566 -12.315162,12.80566 H 24.630317 C 11.083799,230.52117 0,218.99602 0,204.9088 V 25.613462 C 0,11.526214 11.083799,0 24.630317,0 Z"
|
||||||
|
fill="#ffffff" />
|
||||||
|
<path
|
||||||
|
d="m 95.938235,171.30637 c -4.937309,3.5273 -5.29173,10.79088 -0.986794,15.09622 3.456604,3.45693 8.888249,3.80961 12.909149,0.91843 17.21135,-12.13189 40.34975,-12.1288 57.56248,0.006 4.01968,2.89389 9.45266,2.5405 12.90917,-0.9157 4.3029,-4.30251 3.88002,-11.49764 -0.98794,-15.0962 -11.86415,-8.51607 -26.09996,-13.09864 -40.70296,-13.09979 -14.6039,-0.002 -28.83923,4.57651 -40.703105,13.09041 z m -28.793004,-28.2091 c -4.514216,3.80905 -4.867485,10.65089 -0.705527,14.81323 3.598144,3.59848 9.311807,3.95166 13.191659,0.77807 33.013047,-27.22619 80.982517,-27.21992 113.997227,0.0127 3.87958,3.17609 9.52319,2.75301 13.12136,-0.84482 4.23191,-4.23154 3.80866,-11.14497 -0.77709,-14.88357 -40.35143,-32.8785 -98.54865,-32.81432 -138.827629,0.12435 z"
|
||||||
|
fill="#ffffff" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.9 KiB |
3
receivers/electron/assets/icons/player/icon24_cc_off.svg
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M20.8 3.75H3.2C1.9867 3.75 1 4.67503 1 5.8125V18.1875C1 19.325 1.9867 20.25 3.2 20.25H20.8C22.0133 20.25 23 19.325 23 18.1875V5.8125C23 4.67503 22.0133 3.75 20.8 3.75ZM10.9 9.9375H7.6V14.0625H10.9V16.125H7.6C6.3867 16.125 5.4 15.2 5.4 14.0625V9.9375C5.4 8.80003 6.3867 7.875 7.6 7.875H10.9V9.9375ZM18.6 9.9375H15.3V14.0625H18.6V16.125H15.3C14.0867 16.125 13.1 15.2 13.1 14.0625V9.9375C13.1 8.80003 14.0867 7.875 15.3 7.875H18.6V9.9375Z" fill="#595959"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 566 B |
|
@ -0,0 +1,3 @@
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M20.8 3.75H3.2C1.9867 3.75 1 4.67503 1 5.8125V18.1875C1 19.325 1.9867 20.25 3.2 20.25H20.8C22.0133 20.25 23 19.325 23 18.1875V5.8125C23 4.67503 22.0133 3.75 20.8 3.75ZM10.9 9.9375H7.6V14.0625H10.9V16.125H7.6C6.3867 16.125 5.4 15.2 5.4 14.0625V9.9375C5.4 8.80003 6.3867 7.875 7.6 7.875H10.9V9.9375ZM18.6 9.9375H15.3V14.0625H18.6V16.125H15.3C14.0867 16.125 13.1 15.2 13.1 14.0625V9.9375C13.1 8.80003 14.0867 7.875 15.3 7.875H18.6V9.9375Z" fill="#8f8f8f"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 566 B |
3
receivers/electron/assets/icons/player/icon24_cc_on.svg
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M20.8 3.75H3.2C1.9867 3.75 1 4.67503 1 5.8125V18.1875C1 19.325 1.9867 20.25 3.2 20.25H20.8C22.0133 20.25 23 19.325 23 18.1875V5.8125C23 4.67503 22.0133 3.75 20.8 3.75ZM10.9 9.9375H7.6V14.0625H10.9V16.125H7.6C6.3867 16.125 5.4 15.2 5.4 14.0625V9.9375C5.4 8.80003 6.3867 7.875 7.6 7.875H10.9V9.9375ZM18.6 9.9375H15.3V14.0625H18.6V16.125H15.3C14.0867 16.125 13.1 15.2 13.1 14.0625V9.9375C13.1 8.80003 14.0867 7.875 15.3 7.875H18.6V9.9375Z" fill="#c9c9c9"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 566 B |
|
@ -0,0 +1,3 @@
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M20.8 3.75H3.2C1.9867 3.75 1 4.67503 1 5.8125V18.1875C1 19.325 1.9867 20.25 3.2 20.25H20.8C22.0133 20.25 23 19.325 23 18.1875V5.8125C23 4.67503 22.0133 3.75 20.8 3.75ZM10.9 9.9375H7.6V14.0625H10.9V16.125H7.6C6.3867 16.125 5.4 15.2 5.4 14.0625V9.9375C5.4 8.80003 6.3867 7.875 7.6 7.875H10.9V9.9375ZM18.6 9.9375H15.3V14.0625H18.6V16.125H15.3C14.0867 16.125 13.1 15.2 13.1 14.0625V9.9375C13.1 8.80003 14.0867 7.875 15.3 7.875H18.6V9.9375Z" fill="white"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 564 B |
|
@ -0,0 +1,3 @@
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M19.6652 6.35151C20.1116 6.82018 20.1116 7.58132 19.6652 8.04999L10.5234 17.6485C10.077 18.1172 9.35208 18.1172 8.9057 17.6485L4.33478 12.8492C3.88841 12.3806 3.88841 11.6194 4.33478 11.1508C4.78116 10.6821 5.50608 10.6821 5.95246 11.1508L9.71633 15.0989L18.0511 6.35151C18.4975 5.88283 19.2224 5.88283 19.6688 6.35151H19.6652Z" fill="white"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 456 B |
|
@ -0,0 +1,6 @@
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M7.24976 1H2.24976C2.08558 0.999907 1.92299 1.03218 1.77129 1.09496C1.61959 1.15775 1.48176 1.24982 1.36566 1.36591C1.24957 1.482 1.1575 1.61984 1.09472 1.77154C1.03193 1.92323 0.999663 2.08582 0.999756 2.25V7.25C0.999756 7.58152 1.13145 7.89946 1.36587 8.13388C1.60029 8.3683 1.91824 8.5 2.24976 8.5C2.58128 8.5 2.89922 8.3683 3.13364 8.13388C3.36806 7.89946 3.49976 7.58152 3.49976 7.25V3.5H7.24976C7.58128 3.5 7.89922 3.3683 8.13364 3.13388C8.36806 2.89946 8.49976 2.58152 8.49976 2.25C8.49976 1.91848 8.36806 1.60054 8.13364 1.36612C7.89922 1.1317 7.58128 1 7.24976 1Z" fill="#c9c9c9"/>
|
||||||
|
<path d="M19.7498 1H14.7498C14.4182 1 14.1003 1.1317 13.8659 1.36612C13.6315 1.60054 13.4998 1.91848 13.4998 2.25C13.4998 2.58152 13.6315 2.89946 13.8659 3.13388C14.1003 3.3683 14.4182 3.5 14.7498 3.5H18.4998V7.25C18.4998 7.58152 18.6315 7.89946 18.8659 8.13388C19.1003 8.3683 19.4182 8.5 19.7498 8.5C20.0813 8.5 20.3992 8.3683 20.6336 8.13388C20.8681 7.89946 20.9998 7.58152 20.9998 7.25V2.25C20.9998 2.08582 20.9676 1.92323 20.9048 1.77154C20.842 1.61984 20.7499 1.482 20.6338 1.36591C20.5178 1.24982 20.3799 1.15775 20.2282 1.09496C20.0765 1.03218 19.9139 0.999907 19.7498 1Z" fill="#c9c9c9"/>
|
||||||
|
<path d="M7.24976 18.5H3.49976V14.75C3.49976 14.4185 3.36806 14.1005 3.13364 13.8661C2.89922 13.6317 2.58128 13.5 2.24976 13.5C1.91824 13.5 1.60029 13.6317 1.36587 13.8661C1.13145 14.1005 0.999756 14.4185 0.999756 14.75V19.75C0.999663 19.9142 1.03193 20.0768 1.09472 20.2285C1.1575 20.3802 1.24957 20.518 1.36566 20.6341C1.48176 20.7502 1.61959 20.8423 1.77129 20.905C1.92299 20.9678 2.08558 21.0001 2.24976 21H7.24976C7.58128 21 7.89922 20.8683 8.13364 20.6339C8.36806 20.3995 8.49976 20.0815 8.49976 19.75C8.49976 19.4185 8.36806 19.1005 8.13364 18.8661C7.89922 18.6317 7.58128 18.5 7.24976 18.5Z" fill="#c9c9c9"/>
|
||||||
|
<path d="M19.7498 13.5C19.5856 13.4999 19.423 13.5322 19.2713 13.595C19.1196 13.6577 18.9818 13.7498 18.8657 13.8659C18.7496 13.982 18.6575 14.1198 18.5947 14.2715C18.5319 14.4232 18.4997 14.5858 18.4998 14.75V18.5H14.7498C14.4182 18.5 14.1003 18.6317 13.8659 18.8661C13.6315 19.1005 13.4998 19.4185 13.4998 19.75C13.4998 20.0815 13.6315 20.3995 13.8659 20.6339C14.1003 20.8683 14.4182 21 14.7498 21H19.7498C19.9139 21.0001 20.0765 20.9678 20.2282 20.905C20.3799 20.8423 20.5178 20.7502 20.6338 20.6341C20.7499 20.518 20.842 20.3802 20.9048 20.2285C20.9676 20.0768 20.9998 19.9142 20.9998 19.75V14.75C20.9998 14.5858 20.9676 14.4232 20.9048 14.2715C20.842 14.1198 20.7499 13.982 20.6338 13.8659C20.5178 13.7498 20.3799 13.6577 20.2282 13.595C20.0765 13.5322 19.9139 13.4999 19.7498 13.5Z" fill="#c9c9c9"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.7 KiB |
|
@ -0,0 +1,6 @@
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M7.24976 1H2.24976C2.08558 0.999907 1.92299 1.03218 1.77129 1.09496C1.61959 1.15775 1.48176 1.24982 1.36566 1.36591C1.24957 1.482 1.1575 1.61984 1.09472 1.77154C1.03193 1.92323 0.999663 2.08582 0.999756 2.25V7.25C0.999756 7.58152 1.13145 7.89946 1.36587 8.13388C1.60029 8.3683 1.91824 8.5 2.24976 8.5C2.58128 8.5 2.89922 8.3683 3.13364 8.13388C3.36806 7.89946 3.49976 7.58152 3.49976 7.25V3.5H7.24976C7.58128 3.5 7.89922 3.3683 8.13364 3.13388C8.36806 2.89946 8.49976 2.58152 8.49976 2.25C8.49976 1.91848 8.36806 1.60054 8.13364 1.36612C7.89922 1.1317 7.58128 1 7.24976 1Z" fill="white"/>
|
||||||
|
<path d="M19.7498 1H14.7498C14.4182 1 14.1003 1.1317 13.8659 1.36612C13.6315 1.60054 13.4998 1.91848 13.4998 2.25C13.4998 2.58152 13.6315 2.89946 13.8659 3.13388C14.1003 3.3683 14.4182 3.5 14.7498 3.5H18.4998V7.25C18.4998 7.58152 18.6315 7.89946 18.8659 8.13388C19.1003 8.3683 19.4182 8.5 19.7498 8.5C20.0813 8.5 20.3992 8.3683 20.6336 8.13388C20.8681 7.89946 20.9998 7.58152 20.9998 7.25V2.25C20.9998 2.08582 20.9676 1.92323 20.9048 1.77154C20.842 1.61984 20.7499 1.482 20.6338 1.36591C20.5178 1.24982 20.3799 1.15775 20.2282 1.09496C20.0765 1.03218 19.9139 0.999907 19.7498 1Z" fill="white"/>
|
||||||
|
<path d="M7.24976 18.5H3.49976V14.75C3.49976 14.4185 3.36806 14.1005 3.13364 13.8661C2.89922 13.6317 2.58128 13.5 2.24976 13.5C1.91824 13.5 1.60029 13.6317 1.36587 13.8661C1.13145 14.1005 0.999756 14.4185 0.999756 14.75V19.75C0.999663 19.9142 1.03193 20.0768 1.09472 20.2285C1.1575 20.3802 1.24957 20.518 1.36566 20.6341C1.48176 20.7502 1.61959 20.8423 1.77129 20.905C1.92299 20.9678 2.08558 21.0001 2.24976 21H7.24976C7.58128 21 7.89922 20.8683 8.13364 20.6339C8.36806 20.3995 8.49976 20.0815 8.49976 19.75C8.49976 19.4185 8.36806 19.1005 8.13364 18.8661C7.89922 18.6317 7.58128 18.5 7.24976 18.5Z" fill="white"/>
|
||||||
|
<path d="M19.7498 13.5C19.5856 13.4999 19.423 13.5322 19.2713 13.595C19.1196 13.6577 18.9818 13.7498 18.8657 13.8659C18.7496 13.982 18.6575 14.1198 18.5947 14.2715C18.5319 14.4232 18.4997 14.5858 18.4998 14.75V18.5H14.7498C14.4182 18.5 14.1003 18.6317 13.8659 18.8661C13.6315 19.1005 13.4998 19.4185 13.4998 19.75C13.4998 20.0815 13.6315 20.3995 13.8659 20.6339C14.1003 20.8683 14.4182 21 14.7498 21H19.7498C19.9139 21.0001 20.0765 20.9678 20.2282 20.905C20.3799 20.8423 20.5178 20.7502 20.6338 20.6341C20.7499 20.518 20.842 20.3802 20.9048 20.2285C20.9676 20.0768 20.9998 19.9142 20.9998 19.75V14.75C20.9998 14.5858 20.9676 14.4232 20.9048 14.2715C20.842 14.1198 20.7499 13.982 20.6338 13.8659C20.5178 13.7498 20.3799 13.6577 20.2282 13.595C20.0765 13.5322 19.9139 13.4999 19.7498 13.5Z" fill="white"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.7 KiB |
|
@ -0,0 +1,3 @@
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M2.84351 17.1171V14.5887H9.28498V20.97H6.69635V17.1171H2.84351ZM6.69635 6.88299V3.03015H9.28498V9.41142H2.84351V6.88299H6.69635ZM14.402 20.97V14.5887H20.8435V17.1171H16.9907V20.97H14.402ZM16.9907 6.88299H20.8435V9.41142H14.402V3.03015H16.9907V6.88299Z" fill="#c9c9c9"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 382 B |
|
@ -0,0 +1,3 @@
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M2.84351 17.1171V14.5887H9.28498V20.97H6.69635V17.1171H2.84351ZM6.69635 6.88299V3.03015H9.28498V9.41142H2.84351V6.88299H6.69635ZM14.402 20.97V14.5887H20.8435V17.1171H16.9907V20.97H14.402ZM16.9907 6.88299H20.8435V9.41142H14.402V3.03015H16.9907V6.88299Z" fill="white"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 380 B |
4
receivers/electron/assets/icons/player/icon24_mute.svg
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.9924 14.5755V3.85875C14.9924 3.59609 14.9026 3.36832 14.7232 3.17544C14.5437 2.98255 14.3246 2.88611 14.0659 2.88611C13.8071 2.88611 13.5734 2.98871 13.3647 3.19391L8.444 8.03273L14.9924 14.5755ZM14.9924 17.4027V19.9381C14.9924 20.2007 14.9026 20.4244 14.7232 20.6091C14.5437 20.7938 14.3246 20.8861 14.0659 20.8861C13.7988 20.8861 13.565 20.7876 13.3647 20.5906L8.35661 15.6782H4.42524C4.15814 15.6782 3.93277 15.5879 3.74914 15.4073C3.56551 15.2267 3.47369 15.0051 3.47369 14.7425V9.05437C3.47369 8.79172 3.56551 8.5701 3.74914 8.38953C3.93277 8.20895 4.15814 8.11867 4.42524 8.11867H5.72523C5.76007 8.16978 5.80018 8.21839 5.84555 8.26372L14.9924 17.4027Z" fill="#c9c9c9"/>
|
||||||
|
<path d="M2.70729 1.71153C3.09775 1.32108 3.73078 1.321 4.12133 1.71137L22.062 19.6435C22.4527 20.034 22.4527 20.6673 22.0621 21.0579C21.6717 21.4483 21.0386 21.4484 20.6481 21.0581L2.70746 3.12592C2.31677 2.73542 2.3167 2.10212 2.70729 1.71153Z" fill="#c9c9c9"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
|
@ -0,0 +1,4 @@
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.9924 14.5755V3.85875C14.9924 3.59609 14.9026 3.36832 14.7232 3.17544C14.5437 2.98255 14.3246 2.88611 14.0659 2.88611C13.8071 2.88611 13.5734 2.98871 13.3647 3.19391L8.444 8.03273L14.9924 14.5755ZM14.9924 17.4027V19.9381C14.9924 20.2007 14.9026 20.4244 14.7232 20.6091C14.5437 20.7938 14.3246 20.8861 14.0659 20.8861C13.7988 20.8861 13.565 20.7876 13.3647 20.5906L8.35661 15.6782H4.42524C4.15814 15.6782 3.93277 15.5879 3.74914 15.4073C3.56551 15.2267 3.47369 15.0051 3.47369 14.7425V9.05437C3.47369 8.79172 3.56551 8.5701 3.74914 8.38953C3.93277 8.20895 4.15814 8.11867 4.42524 8.11867H5.72523C5.76007 8.16978 5.80018 8.21839 5.84555 8.26372L14.9924 17.4027Z" fill="white"/>
|
||||||
|
<path d="M2.70729 1.71153C3.09775 1.32108 3.73078 1.321 4.12133 1.71137L22.062 19.6435C22.4527 20.034 22.4527 20.6673 22.0621 21.0579C21.6717 21.4483 21.0386 21.4484 20.6481 21.0581L2.70746 3.12592C2.31677 2.73542 2.3167 2.10212 2.70729 1.71153Z" fill="white"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
3
receivers/electron/assets/icons/player/icon24_pause.svg
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M5 20V4H9.56376V20H5ZM14.1812 4H18.745V20H14.1812V4Z" fill="#c9c9c9"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 183 B |
|
@ -0,0 +1,3 @@
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M5 20V4H9.56376V20H5ZM14.1812 4H18.745V20H14.1812V4Z" fill="white"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 181 B |
3
receivers/electron/assets/icons/player/icon24_play.svg
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M6.34282 20C5.9769 20 5.67501 19.8658 5.43716 19.5975C5.19931 19.3291 5.08038 18.9693 5.08038 18.518V5.47284C5.08038 5.02154 5.19931 4.66476 5.43716 4.40252C5.67501 4.13417 5.9769 4 6.34282 4C6.53798 4 6.72399 4.03354 6.90085 4.10063C7.08381 4.16771 7.27897 4.2592 7.48633 4.37507L18.2719 10.6232C18.6683 10.8489 18.9519 11.0623 19.1227 11.2636C19.2935 11.4648 19.3788 11.7088 19.3788 11.9954C19.3788 12.2821 19.2935 12.526 19.1227 12.7273C18.9519 12.9285 18.6683 13.145 18.2719 13.3768L7.48633 19.6158C7.27897 19.7378 7.08381 19.8323 6.90085 19.8994C6.72399 19.9665 6.53798 20 6.34282 20Z" fill="#c9c9c9"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 720 B |
|
@ -0,0 +1,3 @@
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M6.34282 20C5.9769 20 5.67501 19.8658 5.43716 19.5975C5.19931 19.3291 5.08038 18.9693 5.08038 18.518V5.47284C5.08038 5.02154 5.19931 4.66476 5.43716 4.40252C5.67501 4.13417 5.9769 4 6.34282 4C6.53798 4 6.72399 4.03354 6.90085 4.10063C7.08381 4.16771 7.27897 4.2592 7.48633 4.37507L18.2719 10.6232C18.6683 10.8489 18.9519 11.0623 19.1227 11.2636C19.2935 11.4648 19.3788 11.7088 19.3788 11.9954C19.3788 12.2821 19.2935 12.526 19.1227 12.7273C18.9519 12.9285 18.6683 13.145 18.2719 13.3768L7.48633 19.6158C7.27897 19.7378 7.08381 19.8323 6.90085 19.8994C6.72399 19.9665 6.53798 20 6.34282 20Z" fill="white"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 718 B |
17
receivers/electron/assets/icons/player/icon24_speed.svg
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path
|
||||||
|
d="M 13.7129,1.20037 C 13.5599,1.1763 13.4038,1.18275 13.2534,1.21936 13.1029,1.25597 12.9611,1.32202 12.8361,1.41374 12.711,1.50546 12.6052,1.62105 12.5245,1.75392 c -0.0806,0.13287 -0.1344,0.28041 -0.1584,0.43419 -0.0239,0.15379 -0.0175,0.31081 0.0189,0.4621 0.0364,0.1513 0.1021,0.2939 0.1933,0.41967 0.0912,0.12576 0.2061,0.23223 0.3383,0.31333 0.1321,0.08109 0.2788,0.13522 0.4317,0.15929 3.389098,0.232344 5.207929,2.038111 6.604054,4.253237 1.118996,1.775427 1.325364,4.141017 0.792011,6.245906 -0.430385,1.678707 -1.358294,3.188482 -2.663099,4.333639 -1.304899,1.145121 -2.926554,1.872712 -4.654699,2.088365 -0.157845,0.01485 -0.311047,0.06109 -0.450441,0.135992 -0.139396,0.07491 -0.262211,0.176936 -0.361116,0.300045 -0.09891,0.123118 -0.171919,0.264807 -0.21471,0.416667 -0.04279,0.151859 -0.05447,0.310816 -0.03436,0.467418 0.0201,0.156603 0.07167,0.307691 0.151516,0.444297 0.07976,0.136572 0.186337,0.25591 0.31331,0.350903 0.126873,0.09498 0.271635,0.163699 0.42563,0.202072 0.153995,0.03837 0.314022,0.0456 0.470684,0.02128 2.551396,-0.319899 4.90852,-1.514905 6.665935,-3.379393 1.757318,-1.864512 2.80501,-4.281972 2.962701,-6.836347 C 23.513427,10.032106 22.806641,7.372284 21.257196,5.427038 19.461266,3.172344 17.377145,1.625939 13.7129,1.20037 Z"
|
||||||
|
fill="#c9c9c9" />
|
||||||
|
<path
|
||||||
|
d="M 8.07143,15.3046 V 9.35604 C 8.07157,9.08675 8.14013,8.82197 8.2706,8.58682 8.40107,8.35166 8.58912,8.15394 8.81691,8.0124 9.04469,7.87086 9.30467,7.79021 9.57215,7.77809 9.83964,7.76598 10.1058,7.8228 10.3453,7.94317 l 5.9148,2.97433 c 0.2607,0.1313 0.4799,0.3331 0.6331,0.5826 0.1531,0.2495 0.2343,0.537 0.2343,0.8302 0,0.2933 -0.0812,0.5807 -0.2343,0.8302 -0.1532,0.2496 -0.3724,0.4513 -0.6331,0.5827 l -5.9148,2.9743 C 10.1058,16.8378 9.83964,16.8947 9.57215,16.8826 9.30467,16.8704 9.04469,16.7898 8.81691,16.6482 8.58912,16.5067 8.40107,16.309 8.2706,16.0738 8.14013,15.8387 8.07157,15.5739 8.07143,15.3046 Z"
|
||||||
|
fill="#c9c9c9" />
|
||||||
|
<path
|
||||||
|
d="M 10.6863,2.31225 C 10.725,2.46314 10.7338,2.62022 10.7121,2.77452 10.6904,2.92881 10.6387,3.07729 10.5598,3.21146 10.481,3.34562 10.3767,3.46284 10.2528,3.55641 10.1289,3.64997 9.98781,3.71804 9.83771,3.75673 9.44403,3.8586 9.05806,3.98852 8.68271,4.1455 8.53981,4.20527 8.38659,4.23615 8.23182,4.23637 8.07705,4.23659 7.92375,4.20616 7.78068,4.14679 7.6376,4.08743 7.50755,4.00031 7.39796,3.8904 7.28836,3.7805 7.20136,3.64996 7.14193,3.50624 7.0825,3.36251 7.05179,3.20843 7.05157,3.05277 7.05135,2.89712 7.08162,2.74295 7.14064,2.59905 7.19967,2.45516 7.28629,2.32437 7.39558,2.21415 7.50486,2.10393 7.63467,2.01644 7.77757,1.95667 8.25214,1.75754 8.744,1.5916 9.25157,1.46043 9.40149,1.42171 9.55753,1.41307 9.71078,1.435 c 0.15324,0.02194 0.30072,0.07402 0.43392,0.15327 0.1332,0.07924 0.2496,0.18411 0.3425,0.3086 0.093,0.1245 0.1606,0.2646 0.1991,0.41538 z M 6.005,4.26087 C 6.2224,4.48645 6.34188,4.78959 6.33716,5.10371 6.33245,5.41782 6.20393,5.71721 5.97986,5.93608 5.39555,6.50882 4.89314,7.16036 4.487,7.87205 4.4123,8.01106 4.31071,8.13365 4.18821,8.2326 4.06572,8.33156 3.92478,8.40488 3.7737,8.44826 3.62261,8.49163 3.46443,8.50419 3.30845,8.48519 3.15247,8.46619 3.00185,8.41602 2.86543,8.33762 2.72901,8.25922 2.60956,8.15419 2.51409,8.02868 2.41862,7.90318 2.34907,7.75975 2.30953,7.60682 2.26999,7.45389 2.26125,7.29455 2.28382,7.13818 2.3064,6.9818 2.35984,6.83155 2.441,6.69625 2.95566,5.7904 3.59471,4.96203 4.33929,4.23558 4.56358,4.01694 4.86501,3.89679 5.17735,3.90153 5.48968,3.90627 5.78737,4.03552 6.005,4.26087 Z"
|
||||||
|
fill="#c9c9c9" />
|
||||||
|
<path
|
||||||
|
d="m 2.5268743,9.5228951 c 0.3098728,0.046129 0.589468,0.2134487 0.7773467,0.4652329 0.1878804,0.25177 0.2686758,0.567403 0.22464,0.877519 -0.1136188,0.810272 -0.1142716,1.633023 -0.00195,2.44471 0.025607,0.155718 0.019891,0.314829 -0.016815,0.467963 -0.036692,0.153135 -0.103645,0.297209 -0.1968964,0.423744 -0.093265,0.126534 -0.2109436,0.232979 -0.3461307,0.313074 -0.1351869,0.08009 -0.285141,0.132222 -0.4410639,0.153317 -0.155923,0.0211 -0.3146436,0.01076 -0.4668564,-0.03047 C 1.9069428,14.596772 1.7643374,14.525546 1.6397164,14.428487 1.5150953,14.331426 1.4109697,14.2105 1.3334655,14.072826 1.2559631,13.935137 1.2066531,13.783482 1.1884279,13.626763 1.043654,12.595027 1.0447093,11.548805 1.1915583,10.518968 1.2359088,10.2089 1.4014648,9.9298163 1.6518506,9.7430394 1.9022287,9.5562686 2.2169594,9.4770886 2.5268743,9.5228951 Z"
|
||||||
|
fill="#c9c9c9" />
|
||||||
|
<path
|
||||||
|
d="m 2.9263167,15.692773 c 0.2757306,-0.148735 0.5998338,-0.182299 0.9011147,-0.09328 0.3012739,0.089 0.5550776,0.293292 0.7056331,0.567965 0.3945227,0.716798 0.886966,1.375904 1.4632309,1.958459 0.1138029,0.10933 0.2045599,0.240142 0.266925,0.384737 0.062378,0.144591 0.095098,0.300056 0.096254,0.457235 0.00115,0.157187 -0.029296,0.312918 -0.089537,0.458044 -0.060243,0.145126 -0.1490677,0.276708 -0.2612635,0.387021 -0.112196,0.110313 -0.2454778,0.197121 -0.3920371,0.255324 -0.1465494,0.05821 -0.3033987,0.08662 -0.4613283,0.08359 -0.1579298,-0.003 -0.3137503,-0.03748 -0.4582919,-0.101261 C 4.5524683,19.986807 4.4221224,19.894932 4.3136299,19.780379 3.5795376,19.04109 2.9535201,18.202827 2.4540459,17.290329 2.3037709,17.015508 2.2691013,16.692871 2.3576556,16.39331 2.4462071,16.093759 2.6507458,15.841788 2.9263167,15.692773 Z m 4.1953049,4.873184 c 0.1254576,-0.286226 0.3601429,-0.510811 0.6524735,-0.624396 0.2923085,-0.113581 0.618309,-0.106861 0.9063581,0.01865 0.3756122,0.163711 0.762213,0.30108 1.156869,0.411084 0.3028188,0.08453 0.5598248,0.285213 0.7145048,0.55787 0.154676,0.272665 0.194271,0.594953 0.110218,0.89602 -0.08406,0.301066 -0.284866,0.556237 -0.55841,0.709339 -0.273548,0.153148 -0.5973332,0.19167 -0.9001528,0.107127 C 8.6966635,22.50016 8.2055345,22.325523 7.7348173,22.119051 7.4469054,21.993382 7.2204524,21.759141 7.1055001,21.467913 6.9904996,21.176672 6.9963029,20.852243 7.1216216,20.565957 Z"
|
||||||
|
fill="#c9c9c9" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 5.8 KiB |
|
@ -0,0 +1,17 @@
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path
|
||||||
|
d="M 13.7129,1.20037 C 13.5599,1.1763 13.4038,1.18275 13.2534,1.21936 13.1029,1.25597 12.9611,1.32202 12.8361,1.41374 12.711,1.50546 12.6052,1.62105 12.5245,1.75392 c -0.0806,0.13287 -0.1344,0.28041 -0.1584,0.43419 -0.0239,0.15379 -0.0175,0.31081 0.0189,0.4621 0.0364,0.1513 0.1021,0.2939 0.1933,0.41967 0.0912,0.12576 0.2061,0.23223 0.3383,0.31333 0.1321,0.08109 0.2788,0.13522 0.4317,0.15929 3.389098,0.232344 5.207929,2.038111 6.604054,4.253237 1.118996,1.775427 1.325364,4.141017 0.792011,6.245906 -0.430385,1.678707 -1.358294,3.188482 -2.663099,4.333639 -1.304899,1.145121 -2.926554,1.872712 -4.654699,2.088365 -0.157845,0.01485 -0.311047,0.06109 -0.450441,0.135992 -0.139396,0.07491 -0.262211,0.176936 -0.361116,0.300045 -0.09891,0.123118 -0.171919,0.264807 -0.21471,0.416667 -0.04279,0.151859 -0.05447,0.310816 -0.03436,0.467418 0.0201,0.156603 0.07167,0.307691 0.151516,0.444297 0.07976,0.136572 0.186337,0.25591 0.31331,0.350903 0.126873,0.09498 0.271635,0.163699 0.42563,0.202072 0.153995,0.03837 0.314022,0.0456 0.470684,0.02128 2.551396,-0.319899 4.90852,-1.514905 6.665935,-3.379393 1.757318,-1.864512 2.80501,-4.281972 2.962701,-6.836347 C 23.513427,10.032106 22.806641,7.372284 21.257196,5.427038 19.461266,3.172344 17.377145,1.625939 13.7129,1.20037 Z"
|
||||||
|
fill="#ffffff" />
|
||||||
|
<path
|
||||||
|
d="M 8.07143,15.3046 V 9.35604 C 8.07157,9.08675 8.14013,8.82197 8.2706,8.58682 8.40107,8.35166 8.58912,8.15394 8.81691,8.0124 9.04469,7.87086 9.30467,7.79021 9.57215,7.77809 9.83964,7.76598 10.1058,7.8228 10.3453,7.94317 l 5.9148,2.97433 c 0.2607,0.1313 0.4799,0.3331 0.6331,0.5826 0.1531,0.2495 0.2343,0.537 0.2343,0.8302 0,0.2933 -0.0812,0.5807 -0.2343,0.8302 -0.1532,0.2496 -0.3724,0.4513 -0.6331,0.5827 l -5.9148,2.9743 C 10.1058,16.8378 9.83964,16.8947 9.57215,16.8826 9.30467,16.8704 9.04469,16.7898 8.81691,16.6482 8.58912,16.5067 8.40107,16.309 8.2706,16.0738 8.14013,15.8387 8.07157,15.5739 8.07143,15.3046 Z"
|
||||||
|
fill="#ffffff" />
|
||||||
|
<path
|
||||||
|
d="M 10.6863,2.31225 C 10.725,2.46314 10.7338,2.62022 10.7121,2.77452 10.6904,2.92881 10.6387,3.07729 10.5598,3.21146 10.481,3.34562 10.3767,3.46284 10.2528,3.55641 10.1289,3.64997 9.98781,3.71804 9.83771,3.75673 9.44403,3.8586 9.05806,3.98852 8.68271,4.1455 8.53981,4.20527 8.38659,4.23615 8.23182,4.23637 8.07705,4.23659 7.92375,4.20616 7.78068,4.14679 7.6376,4.08743 7.50755,4.00031 7.39796,3.8904 7.28836,3.7805 7.20136,3.64996 7.14193,3.50624 7.0825,3.36251 7.05179,3.20843 7.05157,3.05277 7.05135,2.89712 7.08162,2.74295 7.14064,2.59905 7.19967,2.45516 7.28629,2.32437 7.39558,2.21415 7.50486,2.10393 7.63467,2.01644 7.77757,1.95667 8.25214,1.75754 8.744,1.5916 9.25157,1.46043 9.40149,1.42171 9.55753,1.41307 9.71078,1.435 c 0.15324,0.02194 0.30072,0.07402 0.43392,0.15327 0.1332,0.07924 0.2496,0.18411 0.3425,0.3086 0.093,0.1245 0.1606,0.2646 0.1991,0.41538 z M 6.005,4.26087 C 6.2224,4.48645 6.34188,4.78959 6.33716,5.10371 6.33245,5.41782 6.20393,5.71721 5.97986,5.93608 5.39555,6.50882 4.89314,7.16036 4.487,7.87205 4.4123,8.01106 4.31071,8.13365 4.18821,8.2326 4.06572,8.33156 3.92478,8.40488 3.7737,8.44826 3.62261,8.49163 3.46443,8.50419 3.30845,8.48519 3.15247,8.46619 3.00185,8.41602 2.86543,8.33762 2.72901,8.25922 2.60956,8.15419 2.51409,8.02868 2.41862,7.90318 2.34907,7.75975 2.30953,7.60682 2.26999,7.45389 2.26125,7.29455 2.28382,7.13818 2.3064,6.9818 2.35984,6.83155 2.441,6.69625 2.95566,5.7904 3.59471,4.96203 4.33929,4.23558 4.56358,4.01694 4.86501,3.89679 5.17735,3.90153 5.48968,3.90627 5.78737,4.03552 6.005,4.26087 Z"
|
||||||
|
fill="#ffffff" />
|
||||||
|
<path
|
||||||
|
d="m 2.5268743,9.5228951 c 0.3098728,0.046129 0.589468,0.2134487 0.7773467,0.4652329 0.1878804,0.25177 0.2686758,0.567403 0.22464,0.877519 -0.1136188,0.810272 -0.1142716,1.633023 -0.00195,2.44471 0.025607,0.155718 0.019891,0.314829 -0.016815,0.467963 -0.036692,0.153135 -0.103645,0.297209 -0.1968964,0.423744 -0.093265,0.126534 -0.2109436,0.232979 -0.3461307,0.313074 -0.1351869,0.08009 -0.285141,0.132222 -0.4410639,0.153317 -0.155923,0.0211 -0.3146436,0.01076 -0.4668564,-0.03047 C 1.9069428,14.596772 1.7643374,14.525546 1.6397164,14.428487 1.5150953,14.331426 1.4109697,14.2105 1.3334655,14.072826 1.2559631,13.935137 1.2066531,13.783482 1.1884279,13.626763 1.043654,12.595027 1.0447093,11.548805 1.1915583,10.518968 1.2359088,10.2089 1.4014648,9.9298163 1.6518506,9.7430394 1.9022287,9.5562686 2.2169594,9.4770886 2.5268743,9.5228951 Z"
|
||||||
|
fill="#ffffff" />
|
||||||
|
<path
|
||||||
|
d="m 2.9263167,15.692773 c 0.2757306,-0.148735 0.5998338,-0.182299 0.9011147,-0.09328 0.3012739,0.089 0.5550776,0.293292 0.7056331,0.567965 0.3945227,0.716798 0.886966,1.375904 1.4632309,1.958459 0.1138029,0.10933 0.2045599,0.240142 0.266925,0.384737 0.062378,0.144591 0.095098,0.300056 0.096254,0.457235 0.00115,0.157187 -0.029296,0.312918 -0.089537,0.458044 -0.060243,0.145126 -0.1490677,0.276708 -0.2612635,0.387021 -0.112196,0.110313 -0.2454778,0.197121 -0.3920371,0.255324 -0.1465494,0.05821 -0.3033987,0.08662 -0.4613283,0.08359 -0.1579298,-0.003 -0.3137503,-0.03748 -0.4582919,-0.101261 C 4.5524683,19.986807 4.4221224,19.894932 4.3136299,19.780379 3.5795376,19.04109 2.9535201,18.202827 2.4540459,17.290329 2.3037709,17.015508 2.2691013,16.692871 2.3576556,16.39331 2.4462071,16.093759 2.6507458,15.841788 2.9263167,15.692773 Z m 4.1953049,4.873184 c 0.1254576,-0.286226 0.3601429,-0.510811 0.6524735,-0.624396 0.2923085,-0.113581 0.618309,-0.106861 0.9063581,0.01865 0.3756122,0.163711 0.762213,0.30108 1.156869,0.411084 0.3028188,0.08453 0.5598248,0.285213 0.7145048,0.55787 0.154676,0.272665 0.194271,0.594953 0.110218,0.89602 -0.08406,0.301066 -0.284866,0.556237 -0.55841,0.709339 -0.273548,0.153148 -0.5973332,0.19167 -0.9001528,0.107127 C 8.6966635,22.50016 8.2055345,22.325523 7.7348173,22.119051 7.4469054,21.993382 7.2204524,21.759141 7.1055001,21.467913 6.9904996,21.176672 6.9963029,20.852243 7.1216216,20.565957 Z"
|
||||||
|
fill="#ffffff" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 5.8 KiB |
|
@ -0,0 +1,4 @@
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M11.0983 5.42385V18.2487C11.0983 18.4582 11.028 18.6366 10.8872 18.7839C10.7464 18.9312 10.5746 19.0049 10.3717 19.0049C10.1622 19.0049 9.97886 18.9263 9.82174 18.7692L5.89375 14.851H2.81028C2.60079 14.851 2.42403 14.779 2.28 14.635C2.13598 14.4909 2.06396 14.3142 2.06396 14.1047V9.56787C2.06396 9.35838 2.13598 9.18162 2.28 9.0376C2.42403 8.89357 2.60079 8.82156 2.81028 8.82156H5.89375L9.82174 4.89357C9.9854 4.7299 10.1687 4.64807 10.3717 4.64807C10.5746 4.64807 10.7464 4.72499 10.8872 4.87884C11.028 5.03269 11.0983 5.21436 11.0983 5.42385Z" fill="#c9c9c9"/>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M14 7.40483C15.6876 8.24862 16.8506 9.9818 16.8506 12C16.8506 14.0183 15.6876 15.7515 14 16.5839V7.40483Z" fill="#c9c9c9"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 850 B |
|
@ -0,0 +1,4 @@
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M11.0983 5.42385V18.2487C11.0983 18.4582 11.028 18.6366 10.8872 18.7839C10.7464 18.9312 10.5746 19.0049 10.3717 19.0049C10.1622 19.0049 9.97886 18.9263 9.82174 18.7692L5.89375 14.851H2.81028C2.60079 14.851 2.42403 14.779 2.28 14.635C2.13598 14.4909 2.06396 14.3142 2.06396 14.1047V9.56787C2.06396 9.35838 2.13598 9.18162 2.28 9.0376C2.42403 8.89357 2.60079 8.82156 2.81028 8.82156H5.89375L9.82174 4.89357C9.9854 4.7299 10.1687 4.64807 10.3717 4.64807C10.5746 4.64807 10.7464 4.72499 10.8872 4.87884C11.028 5.03269 11.0983 5.21436 11.0983 5.42385Z" fill="white"/>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M14 7.40483C15.6876 8.24862 16.8506 9.9818 16.8506 12C16.8506 14.0183 15.6876 15.7515 14 16.5839V7.40483Z" fill="white"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 846 B |
|
@ -0,0 +1,4 @@
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M11.0983 5.42381V18.2487C11.0983 18.4582 11.028 18.6366 10.8872 18.7839C10.7464 18.9312 10.5746 19.0048 10.3717 19.0048C10.1622 19.0048 9.97886 18.9263 9.82174 18.7691L5.89375 14.851H2.81028C2.60079 14.851 2.42403 14.779 2.28 14.6349C2.13598 14.4909 2.06396 14.3142 2.06396 14.1047V9.56784C2.06396 9.35834 2.13598 9.18158 2.28 9.03756C2.42403 8.89353 2.60079 8.82152 2.81028 8.82152H5.89375L9.82174 4.89353C9.9854 4.72987 10.1687 4.64803 10.3717 4.64803C10.5746 4.64803 10.7464 4.72496 10.8872 4.8788C11.028 5.03265 11.0983 5.21432 11.0983 5.42381Z" fill="#c9c9c9"/>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M14 4.34892V2C18.5724 3.03763 21.9818 7.11973 21.9818 12C21.9818 16.8803 18.5724 20.9624 14 22V19.6511C17.2953 18.6705 19.7013 15.6146 19.7013 12C19.7013 8.38541 17.2953 5.32953 14 4.34892ZM14 7.4048C15.6876 8.24858 16.8506 9.98176 16.8506 12C16.8506 14.0183 15.6876 15.7514 14 16.5838V7.4048Z" fill="#c9c9c9"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1 KiB |
|
@ -0,0 +1,4 @@
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M11.0983 5.42381V18.2487C11.0983 18.4582 11.028 18.6366 10.8872 18.7839C10.7464 18.9312 10.5746 19.0048 10.3717 19.0048C10.1622 19.0048 9.97886 18.9263 9.82174 18.7691L5.89375 14.851H2.81028C2.60079 14.851 2.42403 14.779 2.28 14.6349C2.13598 14.4909 2.06396 14.3142 2.06396 14.1047V9.56784C2.06396 9.35834 2.13598 9.18158 2.28 9.03756C2.42403 8.89353 2.60079 8.82152 2.81028 8.82152H5.89375L9.82174 4.89353C9.9854 4.72987 10.1687 4.64803 10.3717 4.64803C10.5746 4.64803 10.7464 4.72496 10.8872 4.8788C11.028 5.03265 11.0983 5.21432 11.0983 5.42381Z" fill="white"/>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M14 4.34892V2C18.5724 3.03763 21.9818 7.11973 21.9818 12C21.9818 16.8803 18.5724 20.9624 14 22V19.6511C17.2953 18.6705 19.7013 15.6146 19.7013 12C19.7013 8.38541 17.2953 5.32953 14 4.34892ZM14 7.4048C15.6876 8.24858 16.8506 9.98176 16.8506 12C16.8506 14.0183 15.6876 15.7514 14 16.5838V7.4048Z" fill="white"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1 KiB |
|
@ -15,7 +15,7 @@ const APPLICATION_TITLE = 'FCast Receiver';
|
||||||
module.exports = {
|
module.exports = {
|
||||||
packagerConfig: {
|
packagerConfig: {
|
||||||
asar: true,
|
asar: true,
|
||||||
icon: './assets/icons/icon',
|
icon: './assets/icons/app/icon',
|
||||||
// TODO: Windows signing
|
// TODO: Windows signing
|
||||||
osxSign: {},
|
osxSign: {},
|
||||||
osxNotarize: {
|
osxNotarize: {
|
||||||
|
@ -32,7 +32,7 @@ module.exports = {
|
||||||
options: {
|
options: {
|
||||||
categories: ['AudioVideo', 'Audio', 'Video', 'Network', 'Utility'],
|
categories: ['AudioVideo', 'Audio', 'Video', 'Network', 'Utility'],
|
||||||
homepage: 'https://fcast.org/',
|
homepage: 'https://fcast.org/',
|
||||||
icon: './assets/icons/icon.png',
|
icon: './assets/icons/app/icon.png',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -59,7 +59,7 @@ module.exports = {
|
||||||
{ 'x': 120, 'y': 540, 'type': 'position', 'path': '.VolumeIcon.icns' }
|
{ 'x': 120, 'y': 540, 'type': 'position', 'path': '.VolumeIcon.icns' }
|
||||||
],
|
],
|
||||||
format: 'ULFO',
|
format: 'ULFO',
|
||||||
icon: './assets/icons/icon.icns',
|
icon: './assets/icons/app/icon.icns',
|
||||||
name: APPLICATION_TITLE
|
name: APPLICATION_TITLE
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -69,7 +69,7 @@ module.exports = {
|
||||||
options: {
|
options: {
|
||||||
categories: ['AudioVideo', 'Audio', 'Video', 'Network', 'Utility'],
|
categories: ['AudioVideo', 'Audio', 'Video', 'Network', 'Utility'],
|
||||||
homepage: 'https://fcast.org/',
|
homepage: 'https://fcast.org/',
|
||||||
icon: './assets/icons/icon.png',
|
icon: './assets/icons/app/icon.png',
|
||||||
license: 'MIT',
|
license: 'MIT',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -81,7 +81,7 @@ module.exports = {
|
||||||
arch: 'x64',
|
arch: 'x64',
|
||||||
appUserModelId: `org.futo.${APPLICATION_NAME}`,
|
appUserModelId: `org.futo.${APPLICATION_NAME}`,
|
||||||
// TODO: Windows signing
|
// TODO: Windows signing
|
||||||
icon: './assets/icons/icon.ico',
|
icon: './assets/icons/app/icon.ico',
|
||||||
name: APPLICATION_TITLE,
|
name: APPLICATION_TITLE,
|
||||||
programFilesFolderName: APPLICATION_TITLE,
|
programFilesFolderName: APPLICATION_TITLE,
|
||||||
shortcutName: APPLICATION_TITLE,
|
shortcutName: APPLICATION_TITLE,
|
||||||
|
@ -95,7 +95,7 @@ module.exports = {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
hooks: {
|
hooks: {
|
||||||
postPackage: async (config, packageResults) => {
|
postPackage: async (config, packageResults) => {
|
||||||
switch (packageResults.platform) {
|
switch (packageResults.platform) {
|
||||||
case "darwin": {
|
case "darwin": {
|
||||||
let artifactName = `${APPLICATION_NAME}.app`;
|
let artifactName = `${APPLICATION_NAME}.app`;
|
||||||
|
@ -133,7 +133,7 @@ module.exports = {
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`Making a zip distributable for ${e.platform}/${e.arch}`);
|
console.log(`Making a zip distributable for ${e.platform}/${e.arch}`);
|
||||||
const zipName = `${APPLICATION_NAME}-${e.packageJSON.version}-macOS-${e.arch}.zip`;
|
const zipName = `${APPLICATION_NAME}-${e.packageJSON.version}-macOS-${e.arch}.zip`;
|
||||||
const zipPath = path.resolve(process.cwd(), 'out', 'make', 'zip', e.platform, e.arch, zipName);
|
const zipPath = path.resolve(process.cwd(), 'out', 'make', 'zip', e.platform, e.arch, zipName);
|
||||||
|
|
||||||
exec(`mkdir -p ${path.dirname(zipPath)}`, execOutput);
|
exec(`mkdir -p ${path.dirname(zipPath)}`, execOutput);
|
||||||
|
|
542
receivers/electron/package-lock.json
generated
|
@ -1,15 +1,18 @@
|
||||||
{
|
{
|
||||||
"name": "fcast-receiver",
|
"name": "fcast-receiver",
|
||||||
"version": "2.0.0",
|
"version": "1.9.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "fcast-receiver",
|
"name": "fcast-receiver",
|
||||||
"version": "2.0.0",
|
"version": "1.9.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bufferutil": "^4.0.8",
|
"bufferutil": "^4.0.8",
|
||||||
|
"dashjs": "^4.7.4",
|
||||||
|
"extract-zip": "^2.0.1",
|
||||||
|
"hls.js": "^1.5.15",
|
||||||
"http": "^0.0.1-security",
|
"http": "^0.0.1-security",
|
||||||
"https": "^1.0.0",
|
"https": "^1.0.0",
|
||||||
"qrcode": "^1.5.3",
|
"qrcode": "^1.5.3",
|
||||||
|
@ -34,6 +37,7 @@
|
||||||
"@types/jest": "^29.5.11",
|
"@types/jest": "^29.5.11",
|
||||||
"@types/mdns": "^0.0.38",
|
"@types/mdns": "^0.0.38",
|
||||||
"@types/node-forge": "^1.3.10",
|
"@types/node-forge": "^1.3.10",
|
||||||
|
"@types/qrcode": "^1.5.5",
|
||||||
"@types/workerpool": "^6.1.1",
|
"@types/workerpool": "^6.1.1",
|
||||||
"@types/ws": "^8.5.10",
|
"@types/ws": "^8.5.10",
|
||||||
"@types/yargs": "^17.0.33",
|
"@types/yargs": "^17.0.33",
|
||||||
|
@ -743,6 +747,21 @@
|
||||||
"node": ">= 16.4.0"
|
"node": ">= 16.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@electron-forge/cli/node_modules/fs-extra": {
|
||||||
|
"version": "10.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
|
||||||
|
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"graceful-fs": "^4.2.0",
|
||||||
|
"jsonfile": "^6.0.1",
|
||||||
|
"universalify": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@electron-forge/core": {
|
"node_modules/@electron-forge/core": {
|
||||||
"version": "7.5.0",
|
"version": "7.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/@electron-forge/core/-/core-7.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@electron-forge/core/-/core-7.5.0.tgz",
|
||||||
|
@ -822,6 +841,36 @@
|
||||||
"node": ">= 16.4.0"
|
"node": ">= 16.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@electron-forge/core-utils/node_modules/fs-extra": {
|
||||||
|
"version": "10.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
|
||||||
|
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"graceful-fs": "^4.2.0",
|
||||||
|
"jsonfile": "^6.0.1",
|
||||||
|
"universalify": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@electron-forge/core/node_modules/fs-extra": {
|
||||||
|
"version": "10.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
|
||||||
|
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"graceful-fs": "^4.2.0",
|
||||||
|
"jsonfile": "^6.0.1",
|
||||||
|
"universalify": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@electron-forge/maker-base": {
|
"node_modules/@electron-forge/maker-base": {
|
||||||
"version": "7.5.0",
|
"version": "7.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/@electron-forge/maker-base/-/maker-base-7.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@electron-forge/maker-base/-/maker-base-7.5.0.tgz",
|
||||||
|
@ -837,6 +886,21 @@
|
||||||
"node": ">= 16.4.0"
|
"node": ">= 16.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@electron-forge/maker-base/node_modules/fs-extra": {
|
||||||
|
"version": "10.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
|
||||||
|
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"graceful-fs": "^4.2.0",
|
||||||
|
"jsonfile": "^6.0.1",
|
||||||
|
"universalify": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@electron-forge/maker-deb": {
|
"node_modules/@electron-forge/maker-deb": {
|
||||||
"version": "7.5.0",
|
"version": "7.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/@electron-forge/maker-deb/-/maker-deb-7.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@electron-forge/maker-deb/-/maker-deb-7.5.0.tgz",
|
||||||
|
@ -872,6 +936,21 @@
|
||||||
"electron-installer-dmg": "^5.0.1"
|
"electron-installer-dmg": "^5.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@electron-forge/maker-dmg/node_modules/fs-extra": {
|
||||||
|
"version": "10.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
|
||||||
|
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"graceful-fs": "^4.2.0",
|
||||||
|
"jsonfile": "^6.0.1",
|
||||||
|
"universalify": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@electron-forge/maker-rpm": {
|
"node_modules/@electron-forge/maker-rpm": {
|
||||||
"version": "7.5.0",
|
"version": "7.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/@electron-forge/maker-rpm/-/maker-rpm-7.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@electron-forge/maker-rpm/-/maker-rpm-7.5.0.tgz",
|
||||||
|
@ -924,6 +1003,21 @@
|
||||||
"node": ">= 16.4.0"
|
"node": ">= 16.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@electron-forge/maker-zip/node_modules/fs-extra": {
|
||||||
|
"version": "10.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
|
||||||
|
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"graceful-fs": "^4.2.0",
|
||||||
|
"jsonfile": "^6.0.1",
|
||||||
|
"universalify": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@electron-forge/plugin-auto-unpack-natives": {
|
"node_modules/@electron-forge/plugin-auto-unpack-natives": {
|
||||||
"version": "7.5.0",
|
"version": "7.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/@electron-forge/plugin-auto-unpack-natives/-/plugin-auto-unpack-natives-7.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@electron-forge/plugin-auto-unpack-natives/-/plugin-auto-unpack-natives-7.5.0.tgz",
|
||||||
|
@ -1014,6 +1108,21 @@
|
||||||
"node": ">= 16.4.0"
|
"node": ">= 16.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@electron-forge/template-base/node_modules/fs-extra": {
|
||||||
|
"version": "10.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
|
||||||
|
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"graceful-fs": "^4.2.0",
|
||||||
|
"jsonfile": "^6.0.1",
|
||||||
|
"universalify": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@electron-forge/template-vite": {
|
"node_modules/@electron-forge/template-vite": {
|
||||||
"version": "7.5.0",
|
"version": "7.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/@electron-forge/template-vite/-/template-vite-7.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@electron-forge/template-vite/-/template-vite-7.5.0.tgz",
|
||||||
|
@ -1044,6 +1153,36 @@
|
||||||
"node": ">= 16.4.0"
|
"node": ">= 16.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@electron-forge/template-vite-typescript/node_modules/fs-extra": {
|
||||||
|
"version": "10.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
|
||||||
|
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"graceful-fs": "^4.2.0",
|
||||||
|
"jsonfile": "^6.0.1",
|
||||||
|
"universalify": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@electron-forge/template-vite/node_modules/fs-extra": {
|
||||||
|
"version": "10.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
|
||||||
|
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"graceful-fs": "^4.2.0",
|
||||||
|
"jsonfile": "^6.0.1",
|
||||||
|
"universalify": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@electron-forge/template-webpack": {
|
"node_modules/@electron-forge/template-webpack": {
|
||||||
"version": "7.5.0",
|
"version": "7.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/@electron-forge/template-webpack/-/template-webpack-7.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@electron-forge/template-webpack/-/template-webpack-7.5.0.tgz",
|
||||||
|
@ -1074,6 +1213,36 @@
|
||||||
"node": ">= 16.4.0"
|
"node": ">= 16.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@electron-forge/template-webpack-typescript/node_modules/fs-extra": {
|
||||||
|
"version": "10.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
|
||||||
|
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"graceful-fs": "^4.2.0",
|
||||||
|
"jsonfile": "^6.0.1",
|
||||||
|
"universalify": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@electron-forge/template-webpack/node_modules/fs-extra": {
|
||||||
|
"version": "10.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
|
||||||
|
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"graceful-fs": "^4.2.0",
|
||||||
|
"jsonfile": "^6.0.1",
|
||||||
|
"universalify": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@electron-forge/tracer": {
|
"node_modules/@electron-forge/tracer": {
|
||||||
"version": "7.5.0",
|
"version": "7.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/@electron-forge/tracer/-/tracer-7.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@electron-forge/tracer/-/tracer-7.5.0.tgz",
|
||||||
|
@ -1336,6 +1505,21 @@
|
||||||
"node": ">=12.0.0"
|
"node": ">=12.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@electron/osx-sign/node_modules/fs-extra": {
|
||||||
|
"version": "10.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
|
||||||
|
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"graceful-fs": "^4.2.0",
|
||||||
|
"jsonfile": "^6.0.1",
|
||||||
|
"universalify": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@electron/packager": {
|
"node_modules/@electron/packager": {
|
||||||
"version": "18.3.5",
|
"version": "18.3.5",
|
||||||
"resolved": "https://registry.npmjs.org/@electron/packager/-/packager-18.3.5.tgz",
|
"resolved": "https://registry.npmjs.org/@electron/packager/-/packager-18.3.5.tgz",
|
||||||
|
@ -1373,21 +1557,6 @@
|
||||||
"url": "https://github.com/electron/packager?sponsor=1"
|
"url": "https://github.com/electron/packager?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@electron/packager/node_modules/fs-extra": {
|
|
||||||
"version": "11.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz",
|
|
||||||
"integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"graceful-fs": "^4.2.0",
|
|
||||||
"jsonfile": "^6.0.1",
|
|
||||||
"universalify": "^2.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=14.14"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@electron/rebuild": {
|
"node_modules/@electron/rebuild": {
|
||||||
"version": "3.7.0",
|
"version": "3.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-3.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-3.7.0.tgz",
|
||||||
|
@ -1417,6 +1586,21 @@
|
||||||
"node": ">=12.13.0"
|
"node": ">=12.13.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@electron/rebuild/node_modules/fs-extra": {
|
||||||
|
"version": "10.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
|
||||||
|
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"graceful-fs": "^4.2.0",
|
||||||
|
"jsonfile": "^6.0.1",
|
||||||
|
"universalify": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@electron/universal": {
|
"node_modules/@electron/universal": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@electron/universal/-/universal-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@electron/universal/-/universal-2.0.1.tgz",
|
||||||
|
@ -1446,21 +1630,6 @@
|
||||||
"balanced-match": "^1.0.0"
|
"balanced-match": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@electron/universal/node_modules/fs-extra": {
|
|
||||||
"version": "11.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz",
|
|
||||||
"integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"graceful-fs": "^4.2.0",
|
|
||||||
"jsonfile": "^6.0.1",
|
|
||||||
"universalify": "^2.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=14.14"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@electron/universal/node_modules/minimatch": {
|
"node_modules/@electron/universal/node_modules/minimatch": {
|
||||||
"version": "9.0.5",
|
"version": "9.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
|
||||||
|
@ -1497,21 +1666,6 @@
|
||||||
"node": ">=14.14"
|
"node": ">=14.14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@electron/windows-sign/node_modules/fs-extra": {
|
|
||||||
"version": "11.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz",
|
|
||||||
"integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"graceful-fs": "^4.2.0",
|
|
||||||
"jsonfile": "^6.0.1",
|
|
||||||
"universalify": "^2.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=14.14"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@eslint-community/eslint-utils": {
|
"node_modules/@eslint-community/eslint-utils": {
|
||||||
"version": "4.4.0",
|
"version": "4.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
|
||||||
|
@ -1665,6 +1819,21 @@
|
||||||
"node": ">=14.0.0"
|
"node": ">=14.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@futo/electron-wix-msi-linux/node_modules/fs-extra": {
|
||||||
|
"version": "10.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
|
||||||
|
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"graceful-fs": "^4.2.0",
|
||||||
|
"jsonfile": "^6.0.1",
|
||||||
|
"universalify": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@futo/forge-maker-wix-linux": {
|
"node_modules/@futo/forge-maker-wix-linux": {
|
||||||
"version": "7.5.0",
|
"version": "7.5.0",
|
||||||
"resolved": "https://gitlab.futo.org/api/v4/projects/305/packages/npm/@futo/forge-maker-wix-linux/-/@futo/forge-maker-wix-linux-7.5.0.tgz",
|
"resolved": "https://gitlab.futo.org/api/v4/projects/305/packages/npm/@futo/forge-maker-wix-linux/-/@futo/forge-maker-wix-linux-7.5.0.tgz",
|
||||||
|
@ -2566,7 +2735,7 @@
|
||||||
"version": "22.7.7",
|
"version": "22.7.7",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.7.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.7.tgz",
|
||||||
"integrity": "sha512-SRxCrrg9CL/y54aiMCG3edPKdprgMVGDXjA3gB8UmmBW5TcXzRUYAh8EWzTnSJFAd1rgImPELza+A3bJ+qxz8Q==",
|
"integrity": "sha512-SRxCrrg9CL/y54aiMCG3edPKdprgMVGDXjA3gB8UmmBW5TcXzRUYAh8EWzTnSJFAd1rgImPELza+A3bJ+qxz8Q==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"undici-types": "~6.19.2"
|
"undici-types": "~6.19.2"
|
||||||
|
@ -2582,6 +2751,16 @@
|
||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/qrcode": {
|
||||||
|
"version": "1.5.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/qrcode/-/qrcode-1.5.5.tgz",
|
||||||
|
"integrity": "sha512-CdfBi/e3Qk+3Z/fXYShipBT13OJ2fDO2Q2w5CIP5anLTLIndQG9z6P1cnm+8zCWSpm5dnxMFd/uREtb0EXuQzg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/responselike": {
|
"node_modules/@types/responselike": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz",
|
||||||
|
@ -2640,7 +2819,6 @@
|
||||||
"version": "2.10.3",
|
"version": "2.10.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz",
|
||||||
"integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==",
|
"integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -3534,6 +3712,42 @@
|
||||||
],
|
],
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/bcp-47": {
|
||||||
|
"version": "1.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/bcp-47/-/bcp-47-1.0.8.tgz",
|
||||||
|
"integrity": "sha512-Y9y1QNBBtYtv7hcmoX0tR+tUNSFZGZ6OL6vKPObq8BbOhkCoyayF6ogfLTgAli/KuAEbsYHYUNq2AQuY6IuLag==",
|
||||||
|
"dependencies": {
|
||||||
|
"is-alphabetical": "^1.0.0",
|
||||||
|
"is-alphanumerical": "^1.0.0",
|
||||||
|
"is-decimal": "^1.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/wooorm"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/bcp-47-match": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/bcp-47-match/-/bcp-47-match-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-LggQ4YTdjWQSKELZF5JwchnBa1u0pIQSZf5lSdOHEdbVP55h0qICA/FUp3+W99q0xqxYa1ZQizTUH87gecII5w==",
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/wooorm"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/bcp-47-normalize": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/bcp-47-normalize/-/bcp-47-normalize-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-jWZ1Jdu3cs0EZdfCkS0UE9Gg01PtxnChjEBySeB+Zo6nkqtFfnvtoQQgP1qU1Oo4qgJgxhTI6Sf9y/pZIhPs0A==",
|
||||||
|
"dependencies": {
|
||||||
|
"bcp-47": "^1.0.0",
|
||||||
|
"bcp-47-match": "^1.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/wooorm"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/bl": {
|
"node_modules/bl": {
|
||||||
"version": "4.1.0",
|
"version": "4.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
|
||||||
|
@ -3682,7 +3896,6 @@
|
||||||
"version": "0.2.13",
|
"version": "0.2.13",
|
||||||
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
|
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
|
||||||
"integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
|
"integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "*"
|
"node": "*"
|
||||||
|
@ -4139,6 +4352,11 @@
|
||||||
"node": ">= 0.12.0"
|
"node": ">= 0.12.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/codem-isoboxer": {
|
||||||
|
"version": "0.3.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/codem-isoboxer/-/codem-isoboxer-0.3.9.tgz",
|
||||||
|
"integrity": "sha512-4XOTqEzBWrGOZaMd+sTED2hLpzfBbiQCf1W6OBGkIHqk1D8uwy8WFLazVbdQwfDpQ+vf39lqTGPa9IhWW0roTA=="
|
||||||
|
},
|
||||||
"node_modules/collect-v8-coverage": {
|
"node_modules/collect-v8-coverage": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz",
|
||||||
|
@ -4321,11 +4539,34 @@
|
||||||
"node": ">=12.10"
|
"node": ">=12.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/dashjs": {
|
||||||
|
"version": "4.7.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/dashjs/-/dashjs-4.7.4.tgz",
|
||||||
|
"integrity": "sha512-+hldo25QPP3H/NOwqUrvt4uKdMse60/Gsz9AUAnoYfhga8qHWq4nWiojUosOiigbigkDTCAn9ORcvUaKCvmfCA==",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"dependencies": {
|
||||||
|
"bcp-47-match": "^1.0.3",
|
||||||
|
"bcp-47-normalize": "^1.1.1",
|
||||||
|
"codem-isoboxer": "0.3.9",
|
||||||
|
"es6-promise": "^4.2.8",
|
||||||
|
"fast-deep-equal": "2.0.1",
|
||||||
|
"html-entities": "^1.2.1",
|
||||||
|
"imsc": "^1.1.5",
|
||||||
|
"localforage": "^1.7.1",
|
||||||
|
"path-browserify": "^1.0.1",
|
||||||
|
"ua-parser-js": "^1.0.37"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/dashjs/node_modules/fast-deep-equal": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/debug": {
|
"node_modules/debug": {
|
||||||
"version": "4.3.7",
|
"version": "4.3.7",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
|
||||||
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
|
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ms": "^2.1.3"
|
"ms": "^2.1.3"
|
||||||
|
@ -5063,6 +5304,21 @@
|
||||||
"@bitdisaster/exe-icon-extractor": "^1.0.10"
|
"@bitdisaster/exe-icon-extractor": "^1.0.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/electron-wix-msi/node_modules/fs-extra": {
|
||||||
|
"version": "10.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
|
||||||
|
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"graceful-fs": "^4.2.0",
|
||||||
|
"jsonfile": "^6.0.1",
|
||||||
|
"universalify": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/electron/node_modules/@electron/get": {
|
"node_modules/electron/node_modules/@electron/get": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.3.tgz",
|
||||||
|
@ -5183,7 +5439,6 @@
|
||||||
"version": "1.4.4",
|
"version": "1.4.4",
|
||||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
|
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
|
||||||
"integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
|
"integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"once": "^1.4.0"
|
"once": "^1.4.0"
|
||||||
|
@ -5279,6 +5534,11 @@
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
|
"node_modules/es6-promise": {
|
||||||
|
"version": "4.2.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
|
||||||
|
"integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w=="
|
||||||
|
},
|
||||||
"node_modules/escalade": {
|
"node_modules/escalade": {
|
||||||
"version": "3.2.0",
|
"version": "3.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
|
||||||
|
@ -5629,7 +5889,6 @@
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",
|
||||||
"integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==",
|
"integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==",
|
||||||
"dev": true,
|
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"debug": "^4.1.1",
|
"debug": "^4.1.1",
|
||||||
|
@ -5650,7 +5909,6 @@
|
||||||
"version": "5.2.0",
|
"version": "5.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
|
||||||
"integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
|
"integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"pump": "^3.0.0"
|
"pump": "^3.0.0"
|
||||||
|
@ -5747,7 +6005,6 @@
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
|
||||||
"integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
|
"integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"pend": "~1.2.0"
|
"pend": "~1.2.0"
|
||||||
|
@ -5902,18 +6159,7 @@
|
||||||
"node": ">= 12"
|
"node": ">= 12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/fmix": {
|
"node_modules/flora-colossus/node_modules/fs-extra": {
|
||||||
"version": "0.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/fmix/-/fmix-0.1.0.tgz",
|
|
||||||
"integrity": "sha512-Y6hyofImk9JdzU8k5INtTXX1cu8LDlePWDFU5sftm9H+zKCr5SGrVjdhkvsim646cw5zD0nADj8oHyXMZmCZ9w==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"dependencies": {
|
|
||||||
"imul": "^1.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/fs-extra": {
|
|
||||||
"version": "10.1.0",
|
"version": "10.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
|
||||||
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
|
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
|
||||||
|
@ -5928,6 +6174,32 @@
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/fmix": {
|
||||||
|
"version": "0.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fmix/-/fmix-0.1.0.tgz",
|
||||||
|
"integrity": "sha512-Y6hyofImk9JdzU8k5INtTXX1cu8LDlePWDFU5sftm9H+zKCr5SGrVjdhkvsim646cw5zD0nADj8oHyXMZmCZ9w==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"dependencies": {
|
||||||
|
"imul": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/fs-extra": {
|
||||||
|
"version": "11.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz",
|
||||||
|
"integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"graceful-fs": "^4.2.0",
|
||||||
|
"jsonfile": "^6.0.1",
|
||||||
|
"universalify": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.14"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/fs-minipass": {
|
"node_modules/fs-minipass": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
|
||||||
|
@ -6013,6 +6285,21 @@
|
||||||
"node": ">= 12"
|
"node": ">= 12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/galactus/node_modules/fs-extra": {
|
||||||
|
"version": "10.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
|
||||||
|
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"graceful-fs": "^4.2.0",
|
||||||
|
"jsonfile": "^6.0.1",
|
||||||
|
"universalify": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/gar": {
|
"node_modules/gar": {
|
||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/gar/-/gar-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/gar/-/gar-1.0.4.tgz",
|
||||||
|
@ -6419,6 +6706,12 @@
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/hls.js": {
|
||||||
|
"version": "1.5.17",
|
||||||
|
"resolved": "https://registry.npmjs.org/hls.js/-/hls.js-1.5.17.tgz",
|
||||||
|
"integrity": "sha512-wA66nnYFvQa1o4DO/BFgLNRKnBTVXpNeldGRBJ2Y0SvFtdwvFKCbqa9zhHoZLoxHhZ+jYsj3aIBkWQQCPNOhMw==",
|
||||||
|
"license": "Apache-2.0"
|
||||||
|
},
|
||||||
"node_modules/homedir-polyfill": {
|
"node_modules/homedir-polyfill": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
|
||||||
|
@ -6439,6 +6732,12 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
|
"node_modules/html-entities": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.4.0.tgz",
|
||||||
|
"integrity": "sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/html-escaper": {
|
"node_modules/html-escaper": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
|
||||||
|
@ -6586,6 +6885,12 @@
|
||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/immediate": {
|
||||||
|
"version": "3.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
|
||||||
|
"integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/import-fresh": {
|
"node_modules/import-fresh": {
|
||||||
"version": "3.3.0",
|
"version": "3.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
|
||||||
|
@ -6623,6 +6928,15 @@
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/imsc": {
|
||||||
|
"version": "1.1.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/imsc/-/imsc-1.1.5.tgz",
|
||||||
|
"integrity": "sha512-V8je+CGkcvGhgl2C1GlhqFFiUOIEdwXbXLiu1Fcubvvbo+g9inauqT3l0pNYXGoLPBj3jxtZz9t+wCopMkwadQ==",
|
||||||
|
"license": "BSD-2-Clause",
|
||||||
|
"dependencies": {
|
||||||
|
"sax": "1.2.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/imul": {
|
"node_modules/imul": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/imul/-/imul-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/imul/-/imul-1.0.1.tgz",
|
||||||
|
@ -6711,6 +7025,30 @@
|
||||||
"node": ">= 12"
|
"node": ">= 12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/is-alphabetical": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz",
|
||||||
|
"integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/wooorm"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/is-alphanumerical": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz",
|
||||||
|
"integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"is-alphabetical": "^1.0.0",
|
||||||
|
"is-decimal": "^1.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/wooorm"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/is-arrayish": {
|
"node_modules/is-arrayish": {
|
||||||
"version": "0.2.1",
|
"version": "0.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
|
||||||
|
@ -6734,6 +7072,16 @@
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/is-decimal": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz",
|
||||||
|
"integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/wooorm"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/is-docker": {
|
"node_modules/is-docker": {
|
||||||
"version": "2.2.1",
|
"version": "2.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
|
||||||
|
@ -7890,6 +8238,14 @@
|
||||||
"node": ">= 0.8.0"
|
"node": ">= 0.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/lie": {
|
||||||
|
"version": "3.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz",
|
||||||
|
"integrity": "sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==",
|
||||||
|
"dependencies": {
|
||||||
|
"immediate": "~3.0.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/lines-and-columns": {
|
"node_modules/lines-and-columns": {
|
||||||
"version": "1.2.4",
|
"version": "1.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
|
||||||
|
@ -7964,6 +8320,14 @@
|
||||||
"node": ">=6.11.5"
|
"node": ">=6.11.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/localforage": {
|
||||||
|
"version": "1.10.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/localforage/-/localforage-1.10.0.tgz",
|
||||||
|
"integrity": "sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==",
|
||||||
|
"dependencies": {
|
||||||
|
"lie": "3.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/locate-path": {
|
"node_modules/locate-path": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
|
||||||
|
@ -8752,7 +9116,6 @@
|
||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||||
"dev": true,
|
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"wrappy": "1"
|
"wrappy": "1"
|
||||||
|
@ -9013,6 +9376,12 @@
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/path-browserify": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/path-exists": {
|
"node_modules/path-exists": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
||||||
|
@ -9081,7 +9450,6 @@
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
|
||||||
"integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==",
|
"integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/picocolors": {
|
"node_modules/picocolors": {
|
||||||
|
@ -9340,7 +9708,6 @@
|
||||||
"version": "3.0.2",
|
"version": "3.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz",
|
||||||
"integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==",
|
"integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"end-of-stream": "^1.1.0",
|
"end-of-stream": "^1.1.0",
|
||||||
|
@ -10086,6 +10453,11 @@
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
|
"node_modules/sax": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA=="
|
||||||
|
},
|
||||||
"node_modules/schema-utils": {
|
"node_modules/schema-utils": {
|
||||||
"version": "3.3.0",
|
"version": "3.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
|
||||||
|
@ -11090,11 +11462,37 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ua-parser-js": {
|
||||||
|
"version": "1.0.39",
|
||||||
|
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.39.tgz",
|
||||||
|
"integrity": "sha512-k24RCVWlEcjkdOxYmVJgeD/0a1TiSpqLg+ZalVGV9lsnr4yqu0w7tX/x2xX6G4zpkgQnRf89lxuZ1wsbjXM8lw==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/ua-parser-js"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "paypal",
|
||||||
|
"url": "https://paypal.me/faisalman"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/faisalman"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"ua-parser-js": "script/cli.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/undici-types": {
|
"node_modules/undici-types": {
|
||||||
"version": "6.19.8",
|
"version": "6.19.8",
|
||||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
|
||||||
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==",
|
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/unique-filename": {
|
"node_modules/unique-filename": {
|
||||||
|
@ -11582,7 +11980,6 @@
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
|
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
|
||||||
"dev": true,
|
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/write-file-atomic": {
|
"node_modules/write-file-atomic": {
|
||||||
|
@ -11808,7 +12205,6 @@
|
||||||
"version": "2.10.0",
|
"version": "2.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
|
||||||
"integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
|
"integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"buffer-crc32": "~0.2.3",
|
"buffer-crc32": "~0.2.3",
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
"author": "FUTO",
|
"author": "FUTO",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "rm -rf dist/ && webpack --config ./webpack.config.js && cp -r src/player dist/player && cp -r src/main dist/main && cp assets/icons/icon.ico dist/ && cp assets/icons/icon.png dist/ && cp assets/icons/icon512.png dist/",
|
"build": "rm -rf dist/ && webpack --config ./webpack.config.js && rsync -r src/player/* dist/player --exclude *.ts && rsync -r src/main/* dist/main --exclude *.ts && cp assets/icons/app/icon.ico dist/ && cp assets/icons/app/icon.png dist/ && cp assets/icons/app/icon512.png dist/",
|
||||||
"start": "electron-forge start",
|
"start": "electron-forge start",
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
"package": "electron-forge package",
|
"package": "electron-forge package",
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
"@types/jest": "^29.5.11",
|
"@types/jest": "^29.5.11",
|
||||||
"@types/mdns": "^0.0.38",
|
"@types/mdns": "^0.0.38",
|
||||||
"@types/node-forge": "^1.3.10",
|
"@types/node-forge": "^1.3.10",
|
||||||
|
"@types/qrcode": "^1.5.5",
|
||||||
"@types/workerpool": "^6.1.1",
|
"@types/workerpool": "^6.1.1",
|
||||||
"@types/ws": "^8.5.10",
|
"@types/ws": "^8.5.10",
|
||||||
"@types/yargs": "^17.0.33",
|
"@types/yargs": "^17.0.33",
|
||||||
|
@ -44,6 +45,9 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bufferutil": "^4.0.8",
|
"bufferutil": "^4.0.8",
|
||||||
|
"dashjs": "^4.7.4",
|
||||||
|
"extract-zip": "^2.0.1",
|
||||||
|
"hls.js": "^1.5.15",
|
||||||
"http": "^0.0.1-security",
|
"http": "^0.0.1-security",
|
||||||
"https": "^1.0.0",
|
"https": "^1.0.0",
|
||||||
"qrcode": "^1.5.3",
|
"qrcode": "^1.5.3",
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
#!/bin/zsh
|
#!/bin/zsh
|
||||||
mkdir icon.iconset
|
mkdir icon.iconset
|
||||||
sips -z 16 16 ./assets/icons/icon1024.png --out icon.iconset/icon_16x16.png
|
sips -z 16 16 ./assets/icons/app/icon1024.png --out icon.iconset/icon_16x16.png
|
||||||
sips -z 32 32 ./assets/icons/icon1024.png --out icon.iconset/icon_16x16@2x.png
|
sips -z 32 32 ./assets/icons/app/icon1024.png --out icon.iconset/icon_16x16@2x.png
|
||||||
sips -z 32 32 ./assets/icons/icon1024.png --out icon.iconset/icon_32x32.png
|
sips -z 32 32 ./assets/icons/app/icon1024.png --out icon.iconset/icon_32x32.png
|
||||||
sips -z 64 64 ./assets/icons/icon1024.png --out icon.iconset/icon_32x32@2x.png
|
sips -z 64 64 ./assets/icons/app/icon1024.png --out icon.iconset/icon_32x32@2x.png
|
||||||
sips -z 128 128 ./assets/icons/icon1024.png --out icon.iconset/icon_128x128.png
|
sips -z 128 128 ./assets/icons/app/icon1024.png --out icon.iconset/icon_128x128.png
|
||||||
sips -z 256 256 ./assets/icons/icon1024.png --out icon.iconset/icon_128x128@2x.png
|
sips -z 256 256 ./assets/icons/app/icon1024.png --out icon.iconset/icon_128x128@2x.png
|
||||||
sips -z 256 256 ./assets/icons/icon1024.png --out icon.iconset/icon_256x256.png
|
sips -z 256 256 ./assets/icons/app/icon1024.png --out icon.iconset/icon_256x256.png
|
||||||
sips -z 512 512 ./assets/icons/icon1024.png --out icon.iconset/icon_256x256@2x.png
|
sips -z 512 512 ./assets/icons/app/icon1024.png --out icon.iconset/icon_256x256@2x.png
|
||||||
sips -z 512 512 ./assets/icons/icon1024.png --out icon.iconset/icon_512x512.png
|
sips -z 512 512 ./assets/icons/app/icon1024.png --out icon.iconset/icon_512x512.png
|
||||||
cp ./assets/icons/icon1024.png icon.iconset/icon_512x512@2x.png
|
cp ./assets/icons/app/icon1024.png icon.iconset/icon_512x512@2x.png
|
||||||
iconutil -c icns icon.iconset
|
iconutil -c icns icon.iconset
|
||||||
rm -R icon.iconset
|
rm -R icon.iconset
|
||||||
mv icon.icns ./assets/icons/icon.icns
|
mv icon.icns ./assets/icons/app/icon.icns
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import * as mdns from 'mdns-js';
|
import mdns = require('mdns-js');
|
||||||
import * as cp from 'child_process';
|
const cp = require('child_process');
|
||||||
import * as os from 'os';
|
const os = require('os');
|
||||||
|
|
||||||
export class DiscoveryService {
|
export class DiscoveryService {
|
||||||
private serviceTcp: any;
|
private serviceTcp: any;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import * as net from 'net';
|
import net = require('net');
|
||||||
import { EventEmitter } from 'node:events';
|
import { EventEmitter } from 'node:events';
|
||||||
import { PlaybackErrorMessage, PlaybackUpdateMessage, PlayMessage, SeekMessage, SetSpeedMessage, SetVolumeMessage, VersionMessage, VolumeUpdateMessage } from './Packets';
|
import { PlaybackErrorMessage, PlaybackUpdateMessage, PlayMessage, SeekMessage, SetSpeedMessage, SetVolumeMessage, VersionMessage, VolumeUpdateMessage } from './Packets';
|
||||||
import { WebSocket } from 'ws';
|
import { WebSocket } from 'ws';
|
||||||
|
|
|
@ -119,6 +119,8 @@ export default class Main {
|
||||||
Main.playerWindow = new BrowserWindow({
|
Main.playerWindow = new BrowserWindow({
|
||||||
fullscreen: true,
|
fullscreen: true,
|
||||||
autoHideMenuBar: true,
|
autoHideMenuBar: true,
|
||||||
|
minWidth: 515,
|
||||||
|
minHeight: 290,
|
||||||
icon: path.join(__dirname, 'icon512.png'),
|
icon: path.join(__dirname, 'icon512.png'),
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
preload: path.join(__dirname, 'player/preload.js')
|
preload: path.join(__dirname, 'player/preload.js')
|
||||||
|
@ -166,6 +168,15 @@ export default class Main {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ipcMain.handle('is-full-screen', async () => {
|
||||||
|
const window = Main.playerWindow;
|
||||||
|
if (!window) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return window.isFullScreen();
|
||||||
|
});
|
||||||
|
|
||||||
ipcMain.on('toggle-full-screen', () => {
|
ipcMain.on('toggle-full-screen', () => {
|
||||||
const window = Main.playerWindow;
|
const window = Main.playerWindow;
|
||||||
if (!window) {
|
if (!window) {
|
||||||
|
@ -330,7 +341,7 @@ export default class Main {
|
||||||
|
|
||||||
static main(app: Electron.App) {
|
static main(app: Electron.App) {
|
||||||
Main.application = app;
|
Main.application = app;
|
||||||
const argv = yargs(hideBin(process.argv))
|
const argv = yargs(hideBin(process.argv))
|
||||||
.parserConfiguration({
|
.parserConfiguration({
|
||||||
'boolean-negation': false
|
'boolean-negation': false
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import * as net from 'net';
|
import net = require('net');
|
||||||
import { FCastSession, Opcode } from './FCastSession';
|
import { FCastSession, Opcode } from './FCastSession';
|
||||||
import { EventEmitter } from 'node:events';
|
import { EventEmitter } from 'node:events';
|
||||||
import { dialog } from 'electron';
|
import { dialog } from 'electron';
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
const { contextBridge, ipcRenderer } = require('electron');
|
import { contextBridge, ipcRenderer } from 'electron';
|
||||||
|
|
||||||
let deviceInfo;
|
let deviceInfo;
|
||||||
ipcRenderer.on("device-info", (_event, value) => {
|
ipcRenderer.on("device-info", (_event, value) => {
|
|
@ -1,21 +1,11 @@
|
||||||
const options = {
|
import QRCode from 'qrcode';
|
||||||
textTrackSettings: false,
|
|
||||||
autoplay: true,
|
|
||||||
loop: true,
|
|
||||||
controls: false
|
|
||||||
};
|
|
||||||
|
|
||||||
const player = videojs("video-player", options, function onPlayerReady() {
|
|
||||||
player.src({ type: "video/mp4", src: "./c.mp4" });
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
window.electronAPI.onDeviceInfo(renderIPsAndQRCode);
|
window.electronAPI.onDeviceInfo(renderIPsAndQRCode);
|
||||||
|
|
||||||
if(window.electronAPI.getDeviceInfo()) {
|
if(window.electronAPI.getDeviceInfo()) {
|
||||||
console.log("device info already present");
|
console.log("device info already present");
|
||||||
renderIPsAndQRCode();
|
renderIPsAndQRCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderIPsAndQRCode() {
|
function renderIPsAndQRCode() {
|
||||||
const value = window.electronAPI.getDeviceInfo();
|
const value = window.electronAPI.getDeviceInfo();
|
||||||
|
@ -42,12 +32,16 @@ function renderIPsAndQRCode() {
|
||||||
console.log("qr", {json, url, base64});
|
console.log("qr", {json, url, base64});
|
||||||
|
|
||||||
const qrCodeElement = document.getElementById('qr-code');
|
const qrCodeElement = document.getElementById('qr-code');
|
||||||
new QRCode(qrCodeElement, {
|
QRCode.toCanvas(qrCodeElement, url, {
|
||||||
text: url,
|
margin: 0,
|
||||||
width: 256,
|
width: 256,
|
||||||
height: 256,
|
color: {
|
||||||
colorDark : "#000000",
|
dark : "#000000",
|
||||||
colorLight : "#ffffff",
|
light : "#ffffff",
|
||||||
correctLevel : QRCode.CorrectLevel.M
|
},
|
||||||
|
errorCorrectionLevel : "M",
|
||||||
|
},
|
||||||
|
(e) => {
|
||||||
|
console.log(`Error rendering QR Code: ${e}`)
|
||||||
});
|
});
|
||||||
}
|
}
|
|
@ -2,17 +2,13 @@
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<link href="./video-js.min.css" rel="stylesheet">
|
|
||||||
<link rel="stylesheet" href="./style.css" />
|
<link rel="stylesheet" href="./style.css" />
|
||||||
<title>FCast Receiver</title>
|
<title>FCast Receiver</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="main-container">
|
<div id="main-container">
|
||||||
<video id="video-player" class="video-js" controls preload="auto" data-setup='{}' style="object-fit: cover;">
|
<video id="video-player" class="video" autoplay loop>
|
||||||
<p class="vjs-no-js">
|
<source src="../../assets/video/background.mp4" type="video/mp4">
|
||||||
To view this video please enable JavaScript, and consider upgrading to a web browser that
|
|
||||||
<a href="https://videojs.com/html5-video-support/" target="_blank">supports HTML5 video</a>
|
|
||||||
</p>
|
|
||||||
</video>
|
</video>
|
||||||
<div id="overlay">
|
<div id="overlay">
|
||||||
<div id="title">FCast</div>
|
<div id="title">FCast</div>
|
||||||
|
@ -25,7 +21,7 @@
|
||||||
<div>Port<br>46899 (TCP), 46898 (WS)</div>
|
<div>Port<br>46899 (TCP), 46898 (WS)</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="automatic-discovery">Automatic discovery is available via mDNS</div>
|
<div id="automatic-discovery">Automatic discovery is available via mDNS</div>
|
||||||
<div id="qr-code"></div>
|
<canvas id="qr-code"></canvas>
|
||||||
<div id="scan-to-connect" style="font-weight: bold;">Scan to connect</div>
|
<div id="scan-to-connect" style="font-weight: bold;">Scan to connect</div>
|
||||||
</div>
|
</div>
|
||||||
<!--<div id="update-dialog">There is an update available. Do you wish to update?</div>
|
<!--<div id="update-dialog">There is an update available. Do you wish to update?</div>
|
||||||
|
@ -38,9 +34,6 @@
|
||||||
<div id="window-can-be-closed" style="color: #666666; position: absolute; bottom: 0; margin-bottom: 20px;">App will continue to run as tray app when the window is closed</div>
|
<div id="window-can-be-closed" style="color: #666666; position: absolute; bottom: 0; margin-bottom: 20px;">App will continue to run as tray app when the window is closed</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script>window.HELP_IMPROVE_VIDEOJS = false;</script>
|
|
||||||
<script src="./video.min.js"></script>
|
|
||||||
<script src="./qrcode.min.js"></script>
|
|
||||||
<script src="./renderer.js"></script>
|
<script src="./renderer.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
1
receivers/electron/src/main/qrcode.min.js
vendored
|
@ -6,11 +6,13 @@ body, html {
|
||||||
#main-container {
|
#main-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.video-js {
|
.video {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
object-fit: cover;
|
||||||
}
|
}
|
||||||
|
|
||||||
#overlay {
|
#overlay {
|
||||||
|
|
1
receivers/electron/src/main/video-js.min.css
vendored
26
receivers/electron/src/main/video.min.js
vendored
224
receivers/electron/src/player/Player.ts
Normal file
|
@ -0,0 +1,224 @@
|
||||||
|
import dashjs from 'dashjs';
|
||||||
|
import Hls from 'hls.js';
|
||||||
|
|
||||||
|
export enum PlayerType {
|
||||||
|
Html,
|
||||||
|
Dash,
|
||||||
|
Hls,
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Player {
|
||||||
|
private player: dashjs.MediaPlayerClass | HTMLVideoElement
|
||||||
|
private hlsPlayer: Hls | undefined
|
||||||
|
public playerType: PlayerType
|
||||||
|
|
||||||
|
constructor(playerType: PlayerType, player: dashjs.MediaPlayerClass | HTMLVideoElement, hlsPlayer?: Hls) {
|
||||||
|
this.playerType = playerType;
|
||||||
|
this.player = player;
|
||||||
|
this.hlsPlayer = playerType === PlayerType.Hls ? hlsPlayer : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
switch (this.playerType) {
|
||||||
|
case PlayerType.Dash:
|
||||||
|
try {
|
||||||
|
(this.player as dashjs.MediaPlayerClass).destroy();
|
||||||
|
} catch (e) {
|
||||||
|
console.warn("Failed to destroy dash player", e);
|
||||||
|
}
|
||||||
|
this.player = null;
|
||||||
|
this.playerType = null;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PlayerType.Hls:
|
||||||
|
// HLS also uses html player
|
||||||
|
try {
|
||||||
|
this.hlsPlayer.destroy();
|
||||||
|
} catch (e) {
|
||||||
|
console.warn("Failed to destroy hls player", e);
|
||||||
|
}
|
||||||
|
// fall through
|
||||||
|
|
||||||
|
case PlayerType.Html: {
|
||||||
|
const videoPlayer = this.player as HTMLVideoElement;
|
||||||
|
|
||||||
|
videoPlayer.src = "";
|
||||||
|
// videoPlayer.onerror = null;
|
||||||
|
videoPlayer.onloadedmetadata = null;
|
||||||
|
videoPlayer.ontimeupdate = null;
|
||||||
|
videoPlayer.onplay = null;
|
||||||
|
videoPlayer.onpause = null;
|
||||||
|
videoPlayer.onended = null;
|
||||||
|
videoPlayer.ontimeupdate = null;
|
||||||
|
videoPlayer.onratechange = null;
|
||||||
|
videoPlayer.onvolumechange = null;
|
||||||
|
|
||||||
|
this.player = null;
|
||||||
|
this.playerType = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
play() { console.log("Player: play"); this.player.play(); }
|
||||||
|
|
||||||
|
isPaused(): boolean {
|
||||||
|
if (this.playerType === PlayerType.Dash) {
|
||||||
|
return (this.player as dashjs.MediaPlayerClass).isPaused();
|
||||||
|
} else { // HLS, HTML
|
||||||
|
return (this.player as HTMLVideoElement).paused;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pause() { console.log("Player: pause"); this.player.pause(); }
|
||||||
|
|
||||||
|
getVolume(): number {
|
||||||
|
if (this.playerType === PlayerType.Dash) {
|
||||||
|
return (this.player as dashjs.MediaPlayerClass).getVolume();
|
||||||
|
} else { // HLS, HTML
|
||||||
|
return (this.player as HTMLVideoElement).volume;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setVolume(value: number) {
|
||||||
|
console.log(`Player: setVolume ${value}`);
|
||||||
|
const sanitizedVolume = Math.min(1.0, Math.max(0.0, value));
|
||||||
|
|
||||||
|
if (this.playerType === PlayerType.Dash) {
|
||||||
|
(this.player as dashjs.MediaPlayerClass).setVolume(sanitizedVolume);
|
||||||
|
} else { // HLS, HTML
|
||||||
|
(this.player as HTMLVideoElement).volume = sanitizedVolume;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isMuted(): boolean {
|
||||||
|
if (this.playerType === PlayerType.Dash) {
|
||||||
|
return (this.player as dashjs.MediaPlayerClass).isMuted();
|
||||||
|
} else { // HLS, HTML
|
||||||
|
return (this.player as HTMLVideoElement).muted;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setMute(value: boolean) {
|
||||||
|
console.log(`Player: setMute ${value}`);
|
||||||
|
|
||||||
|
if (this.playerType === PlayerType.Dash) {
|
||||||
|
(this.player as dashjs.MediaPlayerClass).setMute(value);
|
||||||
|
} else { // HLS, HTML
|
||||||
|
(this.player as HTMLVideoElement).muted = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getPlaybackRate(): number {
|
||||||
|
if (this.playerType === PlayerType.Dash) {
|
||||||
|
return (this.player as dashjs.MediaPlayerClass).getPlaybackRate();
|
||||||
|
} else { // HLS, HTML
|
||||||
|
return (this.player as HTMLVideoElement).playbackRate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setPlaybackRate(value: number) {
|
||||||
|
console.log(`Player: setPlaybackRate ${value}`);
|
||||||
|
const sanitizedSpeed = Math.min(16.0, Math.max(0.0, value));
|
||||||
|
|
||||||
|
if (this.playerType === PlayerType.Dash) {
|
||||||
|
(this.player as dashjs.MediaPlayerClass).setPlaybackRate(sanitizedSpeed);
|
||||||
|
} else { // HLS, HTML
|
||||||
|
(this.player as HTMLVideoElement).playbackRate = sanitizedSpeed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getDuration(): number {
|
||||||
|
if (this.playerType === PlayerType.Dash) {
|
||||||
|
const videoPlayer = this.player as dashjs.MediaPlayerClass;
|
||||||
|
return isFinite(videoPlayer.duration()) ? videoPlayer.duration() : 0;
|
||||||
|
} else { // HLS, HTML
|
||||||
|
const videoPlayer = this.player as HTMLVideoElement;
|
||||||
|
return isFinite(videoPlayer.duration) ? videoPlayer.duration : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getCurrentTime(): number {
|
||||||
|
if (this.playerType === PlayerType.Dash) {
|
||||||
|
return (this.player as dashjs.MediaPlayerClass).time();
|
||||||
|
} else { // HLS, HTML
|
||||||
|
return (this.player as HTMLVideoElement).currentTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setCurrentTime(value: number) {
|
||||||
|
// console.log(`Player: setCurrentTime ${value}`);
|
||||||
|
const sanitizedTime = Math.min(this.getDuration(), Math.max(0.0, value));
|
||||||
|
|
||||||
|
if (this.playerType === PlayerType.Dash) {
|
||||||
|
(this.player as dashjs.MediaPlayerClass).seek(sanitizedTime);
|
||||||
|
const videoPlayer = this.player as dashjs.MediaPlayerClass;
|
||||||
|
|
||||||
|
if (!videoPlayer.isSeeking()) {
|
||||||
|
videoPlayer.seek(sanitizedTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else { // HLS, HTML
|
||||||
|
(this.player as HTMLVideoElement).currentTime = sanitizedTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getSource(): string {
|
||||||
|
if (this.playerType === PlayerType.Dash) {
|
||||||
|
const videoPlayer = this.player as dashjs.MediaPlayerClass;
|
||||||
|
return videoPlayer.getSource() instanceof String ? videoPlayer.getSource() as string : JSON.stringify(videoPlayer.getSource());
|
||||||
|
} else { // HLS, HTML
|
||||||
|
return (this.player as HTMLVideoElement).src;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getBufferLength(): number {
|
||||||
|
if (this.playerType === PlayerType.Dash) {
|
||||||
|
const dashPlayer = this.player as dashjs.MediaPlayerClass;
|
||||||
|
|
||||||
|
let dashBufferLength = dashPlayer.getBufferLength("video")
|
||||||
|
?? dashPlayer.getBufferLength("audio")
|
||||||
|
?? dashPlayer.getBufferLength("text")
|
||||||
|
?? dashPlayer.getBufferLength("image")
|
||||||
|
?? 0;
|
||||||
|
if (Number.isNaN(dashBufferLength))
|
||||||
|
dashBufferLength = 0;
|
||||||
|
|
||||||
|
dashBufferLength += dashPlayer.time();
|
||||||
|
return dashBufferLength;
|
||||||
|
} else { // HLS, HTML
|
||||||
|
const videoPlayer = this.player as HTMLVideoElement;
|
||||||
|
let maxBuffer = 0;
|
||||||
|
|
||||||
|
if (videoPlayer.buffered) {
|
||||||
|
for (let i = 0; i < videoPlayer.buffered.length; i++) {
|
||||||
|
const start = videoPlayer.buffered.start(i);
|
||||||
|
const end = videoPlayer.buffered.end(i);
|
||||||
|
|
||||||
|
if (videoPlayer.currentTime >= start && videoPlayer.currentTime <= end) {
|
||||||
|
maxBuffer = end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return maxBuffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isCaptionsEnabled(): boolean {
|
||||||
|
if (this.playerType === PlayerType.Dash) {
|
||||||
|
return (this.player as dashjs.MediaPlayerClass).isTextEnabled();
|
||||||
|
} else if (this.playerType === PlayerType.Hls) {
|
||||||
|
return this.hlsPlayer.subtitleDisplay;
|
||||||
|
} else {
|
||||||
|
return false; // HTML captions not currently supported
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enableCaptions(enable: boolean) {
|
||||||
|
if (this.playerType === PlayerType.Dash) {
|
||||||
|
(this.player as dashjs.MediaPlayerClass).enableText(enable);
|
||||||
|
} else if (this.playerType === PlayerType.Hls) {
|
||||||
|
this.hlsPlayer.subtitleDisplay = enable;
|
||||||
|
}
|
||||||
|
// HTML captions not currently supported
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
24
receivers/electron/src/player/Preload.ts
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
import { contextBridge, ipcRenderer } from 'electron';
|
||||||
|
import { PlaybackErrorMessage, PlaybackUpdateMessage, VolumeUpdateMessage } from '../Packets';
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface Window {
|
||||||
|
electronAPI: any;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
contextBridge.exposeInMainWorld('electronAPI', {
|
||||||
|
isFullScreen: () => ipcRenderer.invoke('is-full-screen'),
|
||||||
|
toggleFullScreen: () => ipcRenderer.send('toggle-full-screen'),
|
||||||
|
exitFullScreen: () => ipcRenderer.send('exit-full-screen'),
|
||||||
|
sendPlaybackError: (error: PlaybackErrorMessage) => ipcRenderer.send('send-playback-error', error),
|
||||||
|
sendPlaybackUpdate: (update: PlaybackUpdateMessage) => ipcRenderer.send('send-playback-update', update),
|
||||||
|
sendVolumeUpdate: (update: VolumeUpdateMessage) => ipcRenderer.send('send-volume-update', update),
|
||||||
|
onPlay: (callback: any) => ipcRenderer.on("play", callback),
|
||||||
|
onPause: (callback: any) => ipcRenderer.on("pause", callback),
|
||||||
|
onResume: (callback: any) => ipcRenderer.on("resume", callback),
|
||||||
|
onSeek: (callback: any) => ipcRenderer.on("seek", callback),
|
||||||
|
onSetVolume: (callback: any) => ipcRenderer.on("setvolume", callback),
|
||||||
|
onSetSpeed: (callback: any) => ipcRenderer.on("setspeed", callback)
|
||||||
|
});
|
684
receivers/electron/src/player/Renderer.ts
Normal file
|
@ -0,0 +1,684 @@
|
||||||
|
import dashjs from 'dashjs';
|
||||||
|
import Hls, { LevelLoadedData } from 'hls.js';
|
||||||
|
import { PlaybackUpdateMessage, PlayMessage, SeekMessage, SetSpeedMessage, SetVolumeMessage } from '../Packets';
|
||||||
|
import { Player, PlayerType } from './Player';
|
||||||
|
|
||||||
|
function formatDuration(duration: number) {
|
||||||
|
const totalSeconds = Math.floor(duration);
|
||||||
|
const hours = Math.floor(totalSeconds / 3600);
|
||||||
|
const minutes = Math.floor((totalSeconds % 3600) / 60);
|
||||||
|
const seconds = Math.floor(totalSeconds % 60);
|
||||||
|
|
||||||
|
const paddedMinutes = String(minutes).padStart(2, '0');
|
||||||
|
const paddedSeconds = String(seconds).padStart(2, '0');
|
||||||
|
|
||||||
|
if (hours > 0) {
|
||||||
|
return `${hours}:${paddedMinutes}:${paddedSeconds}`;
|
||||||
|
} else {
|
||||||
|
return `${paddedMinutes}:${paddedSeconds}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendPlaybackUpdate(updateState: number) {
|
||||||
|
const updateMessage = new PlaybackUpdateMessage(Date.now(), player.getCurrentTime(), player.getDuration(), updateState, player.getPlaybackRate());
|
||||||
|
|
||||||
|
if (updateMessage.generationTime > lastPlayerUpdateGenerationTime) {
|
||||||
|
lastPlayerUpdateGenerationTime = updateMessage.generationTime;
|
||||||
|
window.electronAPI.sendPlaybackUpdate(updateMessage);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function onPlayerLoad(value: PlayMessage, currentPlaybackRate?: number, currentVolume?: number) {
|
||||||
|
playerCtrlStateUpdate(PlayerControlEvent.Load);
|
||||||
|
|
||||||
|
// Subtitles break when seeking post stream initialization for the DASH player.
|
||||||
|
// Its currently done on player initialization.
|
||||||
|
if (player.playerType === PlayerType.Hls || player.playerType === PlayerType.Html) {
|
||||||
|
if (value.time) {
|
||||||
|
player.setCurrentTime(value.time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value.speed) {
|
||||||
|
player.setPlaybackRate(value.speed);
|
||||||
|
} else if (currentPlaybackRate) {
|
||||||
|
player.setPlaybackRate(currentPlaybackRate);
|
||||||
|
} else {
|
||||||
|
player.setPlaybackRate(1.0);
|
||||||
|
}
|
||||||
|
playerCtrlStateUpdate(PlayerControlEvent.SetPlaybackRate);
|
||||||
|
|
||||||
|
if (currentVolume) {
|
||||||
|
player.setVolume(currentVolume);
|
||||||
|
}
|
||||||
|
|
||||||
|
playerCtrlStateUpdate(PlayerControlEvent.Play);
|
||||||
|
}
|
||||||
|
|
||||||
|
// HTML elements
|
||||||
|
const videoElement = document.getElementById("videoPlayer") as HTMLVideoElement;
|
||||||
|
const videoCaptions = document.getElementById("videoCaptions") as HTMLDivElement;
|
||||||
|
|
||||||
|
const playerControls = document.getElementById("controls");
|
||||||
|
|
||||||
|
const playerCtrlAction = document.getElementById("action");
|
||||||
|
const playerCtrlVolume = document.getElementById("volume");
|
||||||
|
|
||||||
|
const playerCtrlProgressBar = document.getElementById("progressBar");
|
||||||
|
const playerCtrlProgressBarBuffer = document.getElementById("progressBarBuffer");
|
||||||
|
const playerCtrlProgressBarProgress = document.getElementById("progressBarProgress");
|
||||||
|
const playerCtrlProgressBarPosition = document.getElementById("progressBarPosition");
|
||||||
|
const playerCtrlProgressBarHandle = document.getElementById("progressBarHandle");
|
||||||
|
const PlayerCtrlProgressBarInteractiveArea = document.getElementById("progressBarInteractiveArea");
|
||||||
|
|
||||||
|
const playerCtrlVolumeBar = document.getElementById("volumeBar");
|
||||||
|
const playerCtrlVolumeBarProgress = document.getElementById("volumeBarProgress");
|
||||||
|
const playerCtrlVolumeBarHandle = document.getElementById("volumeBarHandle");
|
||||||
|
const playerCtrlVolumeBarInteractiveArea = document.getElementById("volumeBarInteractiveArea");
|
||||||
|
|
||||||
|
const playerCtrlLiveBadge = document.getElementById("liveBadge");
|
||||||
|
const playerCtrlPosition = document.getElementById("position");
|
||||||
|
const playerCtrlDuration = document.getElementById("duration");
|
||||||
|
|
||||||
|
const playerCtrlCaptions = document.getElementById("captions");
|
||||||
|
const playerCtrlSpeed = document.getElementById("speed");
|
||||||
|
const playerCtrlFullscreen = document.getElementById("fullscreen");
|
||||||
|
|
||||||
|
const playerCtrlSpeedMenu = document.getElementById("speedMenu");
|
||||||
|
let playerCtrlSpeedMenuShown = false;
|
||||||
|
|
||||||
|
|
||||||
|
const playbackRates = ["0.25", "0.50", "0.75", "1.00", "1.25", "1.50", "1.75", "2.00"];
|
||||||
|
const playbackUpdateInterval = 1.0;
|
||||||
|
const livePositionDelta = 5.0;
|
||||||
|
const livePositionWindow = livePositionDelta * 4;
|
||||||
|
let player: Player;
|
||||||
|
let playerPrevTime: number = 0;
|
||||||
|
let lastPlayerUpdateGenerationTime = 0;
|
||||||
|
let isLive = false;
|
||||||
|
let isLivePosition = false;
|
||||||
|
|
||||||
|
|
||||||
|
window.electronAPI.onPlay((_event, value: PlayMessage) => {
|
||||||
|
console.log("Handle play message renderer", value);
|
||||||
|
const currentVolume = player ? player.getVolume() : null;
|
||||||
|
const currentPlaybackRate = player ? player.getPlaybackRate() : null;
|
||||||
|
|
||||||
|
playerPrevTime = 0;
|
||||||
|
|
||||||
|
if (player) {
|
||||||
|
if (player.getSource() === value.url) {
|
||||||
|
if (value.time) {
|
||||||
|
if (Math.abs(value.time - player.getCurrentTime()) < 5000) {
|
||||||
|
console.warn(`Skipped changing video URL because URL and time is (nearly) unchanged: ${value.url}, ${player.getSource()}, ${formatDuration(value.time)}, ${formatDuration(player.getCurrentTime())}`);
|
||||||
|
} else {
|
||||||
|
console.info(`Skipped changing video URL because URL is the same, but time was changed, seeking instead: ${value.url}, ${player.getSource()}, ${formatDuration(value.time)}, ${formatDuration(player.getCurrentTime())}`);
|
||||||
|
|
||||||
|
player.setCurrentTime(value.time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
player.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((value.url || value.content) && value.container && videoElement) {
|
||||||
|
if (value.container === 'application/dash+xml') {
|
||||||
|
console.log("Loading dash player");
|
||||||
|
const dashPlayer = dashjs.MediaPlayer().create();
|
||||||
|
player = new Player(PlayerType.Dash, dashPlayer);
|
||||||
|
|
||||||
|
dashPlayer.extend("RequestModifier", () => {
|
||||||
|
return {
|
||||||
|
modifyRequestHeader: function (xhr) {
|
||||||
|
if (value.headers) {
|
||||||
|
for (const [key, val] of Object.entries(value.headers)) {
|
||||||
|
xhr.setRequestHeader(key, val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return xhr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
// Player event handlers
|
||||||
|
dashPlayer.on(dashjs.MediaPlayer.events.PLAYBACK_PLAYING, () => { sendPlaybackUpdate(1) });
|
||||||
|
dashPlayer.on(dashjs.MediaPlayer.events.PLAYBACK_PAUSED, () => { sendPlaybackUpdate(2) });
|
||||||
|
dashPlayer.on(dashjs.MediaPlayer.events.PLAYBACK_ENDED, () => { sendPlaybackUpdate(0) });
|
||||||
|
dashPlayer.on(dashjs.MediaPlayer.events.PLAYBACK_TIME_UPDATED, () => {
|
||||||
|
playerCtrlStateUpdate(PlayerControlEvent.TimeUpdate);
|
||||||
|
|
||||||
|
console.log(`CALC TIME: ${Math.abs(dashPlayer.time() - playerPrevTime)}`)
|
||||||
|
if (Math.abs(dashPlayer.time() - playerPrevTime) >= playbackUpdateInterval) {
|
||||||
|
sendPlaybackUpdate(dashPlayer.isPaused() ? 2 : 1);
|
||||||
|
playerPrevTime = dashPlayer.time();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
dashPlayer.on(dashjs.MediaPlayer.events.PLAYBACK_RATE_CHANGED, () => { sendPlaybackUpdate(dashPlayer.isPaused() ? 2 : 1) });
|
||||||
|
|
||||||
|
// Buffering UI update when paused
|
||||||
|
dashPlayer.on(dashjs.MediaPlayer.events.PLAYBACK_PROGRESS, () => { playerCtrlStateUpdate(PlayerControlEvent.TimeUpdate); });
|
||||||
|
|
||||||
|
dashPlayer.on(dashjs.MediaPlayer.events.PLAYBACK_VOLUME_CHANGED, () => {
|
||||||
|
playerCtrlStateUpdate(PlayerControlEvent.VolumeChange);
|
||||||
|
window.electronAPI.sendVolumeUpdate({ generationTime: Date.now(), volume: dashPlayer.getVolume() });
|
||||||
|
});
|
||||||
|
|
||||||
|
dashPlayer.on(dashjs.MediaPlayer.events.ERROR, (data) => { window.electronAPI.sendPlaybackError({
|
||||||
|
message: `DashJS ERROR: ${JSON.stringify(data)}`
|
||||||
|
})});
|
||||||
|
|
||||||
|
dashPlayer.on(dashjs.MediaPlayer.events.PLAYBACK_ERROR, (data) => { window.electronAPI.sendPlaybackError({
|
||||||
|
message: `DashJS PLAYBACK_ERROR: ${JSON.stringify(data)}`
|
||||||
|
})});
|
||||||
|
|
||||||
|
dashPlayer.on(dashjs.MediaPlayer.events.STREAM_INITIALIZED, () => { onPlayerLoad(value, currentPlaybackRate, currentVolume); });
|
||||||
|
|
||||||
|
dashPlayer.on(dashjs.MediaPlayer.events.CUE_ENTER, (e: any) => {
|
||||||
|
// console.log("cueEnter", e);
|
||||||
|
const subtitle = document.createElement("p")
|
||||||
|
subtitle.setAttribute("id", "subtitle-" + e.cueID)
|
||||||
|
|
||||||
|
subtitle.textContent = e.text;
|
||||||
|
videoCaptions.appendChild(subtitle);
|
||||||
|
});
|
||||||
|
|
||||||
|
dashPlayer.on(dashjs.MediaPlayer.events.CUE_EXIT, (e: any) => {
|
||||||
|
// console.log("cueExit ", e);
|
||||||
|
document.getElementById("subtitle-" + e.cueID).remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
dashPlayer.updateSettings({
|
||||||
|
streaming: {
|
||||||
|
text: {
|
||||||
|
dispatchForManualRendering: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (value.content) {
|
||||||
|
dashPlayer.initialize(videoElement, `data:${value.container};base64,` + window.btoa(value.content), true, value.time);
|
||||||
|
// dashPlayer.initialize(videoElement, "https://dash.akamaized.net/akamai/test/caption_test/ElephantsDream/elephants_dream_480p_heaac5_1_https.mpd", true);
|
||||||
|
} else {
|
||||||
|
dashPlayer.initialize(videoElement, value.url, true, value.time);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if ((value.container === 'application/vnd.apple.mpegurl' || value.container === 'application/x-mpegURL') && !videoElement.canPlayType(value.container)) {
|
||||||
|
console.log("Loading hls player");
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
xhrSetup: function (xhr: XMLHttpRequest) {
|
||||||
|
if (value.headers) {
|
||||||
|
for (const [key, val] of Object.entries(value.headers)) {
|
||||||
|
xhr.setRequestHeader(key, val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const hlsPlayer = new Hls(config);
|
||||||
|
|
||||||
|
hlsPlayer.on(Hls.Events.ERROR, (eventName, data) => {
|
||||||
|
window.electronAPI.sendPlaybackError({
|
||||||
|
message: `HLS player error: ${JSON.stringify(data)}`
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
hlsPlayer.on(Hls.Events.LEVEL_LOADED, (eventName, level: LevelLoadedData) => {
|
||||||
|
isLive = level.details.live;
|
||||||
|
isLivePosition = isLive ? true : false;
|
||||||
|
});
|
||||||
|
|
||||||
|
player = new Player(PlayerType.Hls, videoElement, hlsPlayer);
|
||||||
|
|
||||||
|
// value.url = "https://devstreaming-cdn.apple.com/videos/streaming/examples/adv_dv_atmos/main.m3u8?ref=developerinsider.co";
|
||||||
|
hlsPlayer.loadSource(value.url);
|
||||||
|
hlsPlayer.attachMedia(videoElement);
|
||||||
|
// hlsPlayer.subtitleDisplay = true;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
console.log("Loading html player");
|
||||||
|
player = new Player(PlayerType.Html, videoElement);
|
||||||
|
|
||||||
|
videoElement.src = value.url;
|
||||||
|
videoElement.load();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Player event handlers
|
||||||
|
if (player.playerType === PlayerType.Hls || player.playerType === PlayerType.Html) {
|
||||||
|
videoElement.onplay = () => { sendPlaybackUpdate(1) };
|
||||||
|
videoElement.onpause = () => { sendPlaybackUpdate(2) };
|
||||||
|
videoElement.onended = () => { sendPlaybackUpdate(0) };
|
||||||
|
videoElement.ontimeupdate = () => {
|
||||||
|
playerCtrlStateUpdate(PlayerControlEvent.TimeUpdate);
|
||||||
|
|
||||||
|
if (Math.abs(videoElement.currentTime - playerPrevTime) >= playbackUpdateInterval) {
|
||||||
|
sendPlaybackUpdate(videoElement.paused ? 2 : 1);
|
||||||
|
playerPrevTime = videoElement.currentTime;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Buffering UI update when paused
|
||||||
|
videoElement.onprogress = () => { playerCtrlStateUpdate(PlayerControlEvent.TimeUpdate); };
|
||||||
|
videoElement.onratechange = () => { sendPlaybackUpdate(videoElement.paused ? 2 : 1) };
|
||||||
|
videoElement.onvolumechange = () => {
|
||||||
|
playerCtrlStateUpdate(PlayerControlEvent.VolumeChange);
|
||||||
|
window.electronAPI.sendVolumeUpdate({ generationTime: Date.now(), volume: videoElement.volume });
|
||||||
|
};
|
||||||
|
|
||||||
|
videoElement.onerror = (event: Event | string, source?: string, lineno?: number, colno?: number, error?: Error) => {
|
||||||
|
console.error("Player error", {source, lineno, colno, error});
|
||||||
|
};
|
||||||
|
|
||||||
|
videoElement.onloadedmetadata = () => { onPlayerLoad(value, currentPlaybackRate, currentVolume); };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sender generated event handlers
|
||||||
|
window.electronAPI.onPause(() => { playerCtrlStateUpdate(PlayerControlEvent.Pause); });
|
||||||
|
window.electronAPI.onResume(() => { playerCtrlStateUpdate(PlayerControlEvent.Play); });
|
||||||
|
window.electronAPI.onSeek((_event, value: SeekMessage) => { player.setCurrentTime(value.time); });
|
||||||
|
window.electronAPI.onSetVolume((_event, value: SetVolumeMessage) => { volumeChangeHandler(value.volume); });
|
||||||
|
window.electronAPI.onSetSpeed((_event, value: SetSpeedMessage) => { player.setPlaybackRate(value.speed); playerCtrlStateUpdate(PlayerControlEvent.SetPlaybackRate); });
|
||||||
|
});
|
||||||
|
|
||||||
|
let scrubbing = false;
|
||||||
|
let volumeChanging = false;
|
||||||
|
|
||||||
|
enum PlayerControlEvent {
|
||||||
|
Load,
|
||||||
|
Pause,
|
||||||
|
Play,
|
||||||
|
ToggleMute,
|
||||||
|
VolumeChange,
|
||||||
|
TimeUpdate,
|
||||||
|
UiFadeOut,
|
||||||
|
UiFadeIn,
|
||||||
|
SetCaptions,
|
||||||
|
ToggleSpeedMenu,
|
||||||
|
SetPlaybackRate,
|
||||||
|
ToggleFullscreen,
|
||||||
|
ExitFullscreen,
|
||||||
|
}
|
||||||
|
|
||||||
|
// UI update handler
|
||||||
|
function playerCtrlStateUpdate(event: PlayerControlEvent) {
|
||||||
|
switch (event) {
|
||||||
|
case PlayerControlEvent.Load: {
|
||||||
|
playerCtrlProgressBarBuffer.setAttribute("style", "width: 0px");
|
||||||
|
playerCtrlProgressBarProgress.setAttribute("style", "width: 0px");
|
||||||
|
playerCtrlProgressBarHandle.setAttribute("style", `left: ${playerCtrlProgressBar.offsetLeft}px`);
|
||||||
|
|
||||||
|
const volume = Math.round(player.getVolume() * playerCtrlVolumeBar.offsetWidth);
|
||||||
|
playerCtrlVolumeBarProgress.setAttribute("style", `width: ${volume}px`);
|
||||||
|
playerCtrlVolumeBarHandle.setAttribute("style", `left: ${volume + 8}px`);
|
||||||
|
|
||||||
|
if (isLive) {
|
||||||
|
playerCtrlLiveBadge.setAttribute("style", "display: block");
|
||||||
|
playerCtrlPosition.setAttribute("style", "display: none");
|
||||||
|
playerCtrlDuration.setAttribute("style", "display: none");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
playerCtrlLiveBadge.setAttribute("style", "display: none");
|
||||||
|
playerCtrlPosition.textContent = formatDuration(player.getCurrentTime());
|
||||||
|
playerCtrlDuration.innerHTML = `/  ${formatDuration(player.getDuration())}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
playerCtrlStateUpdate(PlayerControlEvent.SetCaptions);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PlayerControlEvent.Pause:
|
||||||
|
playerCtrlAction.setAttribute("class", "play");
|
||||||
|
stopUiHideTimer();
|
||||||
|
player.pause();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PlayerControlEvent.Play:
|
||||||
|
playerCtrlAction.setAttribute("class", "pause");
|
||||||
|
|
||||||
|
startUiHideTimer();
|
||||||
|
player.play();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PlayerControlEvent.ToggleMute:
|
||||||
|
player.setMute(!player.isMuted());
|
||||||
|
window.electronAPI.sendVolumeUpdate({ generationTime: Date.now(), volume: 0 });
|
||||||
|
// fallthrough
|
||||||
|
|
||||||
|
case PlayerControlEvent.VolumeChange: {
|
||||||
|
const volume = Math.round(player.getVolume() * playerCtrlVolumeBar.offsetWidth);
|
||||||
|
|
||||||
|
if (player.isMuted()) {
|
||||||
|
playerCtrlVolume.setAttribute("class", "mute");
|
||||||
|
playerCtrlVolumeBarProgress.setAttribute("style", `width: 0px`);
|
||||||
|
playerCtrlVolumeBarHandle.setAttribute("style", `left: 0px`);
|
||||||
|
}
|
||||||
|
else if (player.getVolume() >= 0.5) {
|
||||||
|
playerCtrlVolume.setAttribute("class", "volume_high");
|
||||||
|
playerCtrlVolumeBarProgress.setAttribute("style", `width: ${volume}px`);
|
||||||
|
playerCtrlVolumeBarHandle.setAttribute("style", `left: ${volume}px`);
|
||||||
|
} else {
|
||||||
|
playerCtrlVolume.setAttribute("class", "volume_low");
|
||||||
|
playerCtrlVolumeBarProgress.setAttribute("style", `width: ${volume}px`);
|
||||||
|
playerCtrlVolumeBarHandle.setAttribute("style", `left: ${volume}px`);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PlayerControlEvent.TimeUpdate: {
|
||||||
|
if (isLive) {
|
||||||
|
if (isLivePosition && player.getDuration() - player.getCurrentTime() > livePositionWindow) {
|
||||||
|
isLivePosition = false;
|
||||||
|
playerCtrlLiveBadge.setAttribute("style", `background-color: #595959`);
|
||||||
|
}
|
||||||
|
else if (!isLivePosition && player.getDuration() - player.getCurrentTime() <= livePositionWindow) {
|
||||||
|
isLivePosition = true;
|
||||||
|
playerCtrlLiveBadge.setAttribute("style", `background-color: red`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isLivePosition) {
|
||||||
|
playerCtrlProgressBarProgress.setAttribute("style", `width: ${playerCtrlProgressBar.offsetWidth}px`);
|
||||||
|
playerCtrlProgressBarHandle.setAttribute("style", `left: ${playerCtrlProgressBar.offsetWidth + playerCtrlProgressBar.offsetLeft}px`);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const buffer = Math.round((player.getBufferLength() / player.getDuration()) * playerCtrlProgressBar.offsetWidth);
|
||||||
|
const progress = Math.round((player.getCurrentTime() / player.getDuration()) * playerCtrlProgressBar.offsetWidth);
|
||||||
|
const handle = progress + playerCtrlProgressBar.offsetLeft;
|
||||||
|
|
||||||
|
playerCtrlProgressBarBuffer.setAttribute("style", `width: ${buffer}px`);
|
||||||
|
playerCtrlProgressBarProgress.setAttribute("style", `width: ${progress}px`);
|
||||||
|
playerCtrlProgressBarHandle.setAttribute("style", `left: ${handle}px`);
|
||||||
|
|
||||||
|
playerCtrlPosition.textContent = formatDuration(player.getCurrentTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PlayerControlEvent.UiFadeOut:
|
||||||
|
document.body.style.cursor = "none";
|
||||||
|
playerControls.setAttribute("style", "opacity: 0");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PlayerControlEvent.UiFadeIn:
|
||||||
|
document.body.style.cursor = "default";
|
||||||
|
playerControls.setAttribute("style", "opacity: 1");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PlayerControlEvent.SetCaptions:
|
||||||
|
if (player.isCaptionsEnabled()) {
|
||||||
|
playerCtrlCaptions.setAttribute("class", "captions_on");
|
||||||
|
videoCaptions.setAttribute("style", "display: block");
|
||||||
|
} else {
|
||||||
|
playerCtrlCaptions.setAttribute("class", "captions_off");
|
||||||
|
videoCaptions.setAttribute("style", "display: none");
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PlayerControlEvent.ToggleSpeedMenu: {
|
||||||
|
if (playerCtrlSpeedMenuShown) {
|
||||||
|
playerCtrlSpeedMenu.setAttribute("style", "display: none");
|
||||||
|
} else {
|
||||||
|
playerCtrlSpeedMenu.setAttribute("style", "display: block");
|
||||||
|
}
|
||||||
|
|
||||||
|
playerCtrlSpeedMenuShown = !playerCtrlSpeedMenuShown;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PlayerControlEvent.SetPlaybackRate: {
|
||||||
|
const rate = player.getPlaybackRate().toFixed(2);
|
||||||
|
const entryElement = document.getElementById(`speedMenuEntry_${rate}_enabled`);
|
||||||
|
|
||||||
|
playbackRates.forEach(r => {
|
||||||
|
const entry = document.getElementById(`speedMenuEntry_${r}_enabled`);
|
||||||
|
entry.setAttribute("style", "opacity: 0");
|
||||||
|
});
|
||||||
|
|
||||||
|
// Ignore updating GUI for custom rates
|
||||||
|
if (entryElement !== null) {
|
||||||
|
entryElement.setAttribute("style", "opacity: 1");
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PlayerControlEvent.ToggleFullscreen: {
|
||||||
|
window.electronAPI.toggleFullScreen();
|
||||||
|
|
||||||
|
window.electronAPI.isFullScreen().then((isFullScreen: boolean) => {
|
||||||
|
if (isFullScreen) {
|
||||||
|
playerCtrlFullscreen.setAttribute("class", "fullscreen_on");
|
||||||
|
} else {
|
||||||
|
playerCtrlFullscreen.setAttribute("class", "fullscreen_off");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PlayerControlEvent.ExitFullscreen:
|
||||||
|
window.electronAPI.exitFullScreen();
|
||||||
|
playerCtrlFullscreen.setAttribute("class", "fullscreen_off");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Receiver generated event handlers
|
||||||
|
playerCtrlAction.onclick = () => {
|
||||||
|
if (player.isPaused()) {
|
||||||
|
playerCtrlStateUpdate(PlayerControlEvent.Play);
|
||||||
|
} else {
|
||||||
|
playerCtrlStateUpdate(PlayerControlEvent.Pause);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
playerCtrlVolume.onclick = () => { playerCtrlStateUpdate(PlayerControlEvent.ToggleMute); };
|
||||||
|
|
||||||
|
PlayerCtrlProgressBarInteractiveArea.onmousedown = (e: MouseEvent) => { scrubbing = true; scrubbingMouseHandler(e) };
|
||||||
|
PlayerCtrlProgressBarInteractiveArea.onmouseup = () => { scrubbing = false; };
|
||||||
|
PlayerCtrlProgressBarInteractiveArea.onmouseenter = (e: MouseEvent) => {
|
||||||
|
if (e.buttons === 0) {
|
||||||
|
volumeChanging = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
scrubbingMouseUIHandler(e);
|
||||||
|
};
|
||||||
|
PlayerCtrlProgressBarInteractiveArea.onmouseleave = () => { playerCtrlProgressBarPosition.setAttribute("style", "display: none"); };
|
||||||
|
PlayerCtrlProgressBarInteractiveArea.onmousemove = (e: MouseEvent) => { scrubbingMouseHandler(e) };
|
||||||
|
|
||||||
|
function scrubbingMouseHandler(e: MouseEvent) {
|
||||||
|
const progressBarOffset = e.offsetX - 8;
|
||||||
|
const progressBarWidth = PlayerCtrlProgressBarInteractiveArea.offsetWidth - 16;
|
||||||
|
let time = Math.round((progressBarOffset / progressBarWidth) * player.getDuration());
|
||||||
|
time = Math.min(player.getDuration(), Math.max(0.0, time));
|
||||||
|
|
||||||
|
if (scrubbing && e.buttons === 1) {
|
||||||
|
player.setCurrentTime(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
scrubbingMouseUIHandler(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
function scrubbingMouseUIHandler(e: MouseEvent) {
|
||||||
|
const progressBarOffset = e.offsetX - 8;
|
||||||
|
const progressBarWidth = PlayerCtrlProgressBarInteractiveArea.offsetWidth - 16;
|
||||||
|
let time = isLive ? Math.round((1 - (progressBarOffset / progressBarWidth)) * player.getDuration()) : Math.round((progressBarOffset / progressBarWidth) * player.getDuration());
|
||||||
|
time = Math.min(player.getDuration(), Math.max(0.0, time));
|
||||||
|
|
||||||
|
if (scrubbing && isLive && e.buttons === 1) {
|
||||||
|
isLivePosition = false;
|
||||||
|
playerCtrlLiveBadge.setAttribute("style", `background-color: #595959`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const livePrefix = isLive && Math.floor(time) !== 0 ? "-" : "";
|
||||||
|
playerCtrlProgressBarPosition.textContent = isLive ? `${livePrefix}${formatDuration(time)}` : formatDuration(time);
|
||||||
|
|
||||||
|
let offset = e.offsetX - (playerCtrlProgressBarPosition.offsetWidth / 2);
|
||||||
|
offset = Math.min(PlayerCtrlProgressBarInteractiveArea.offsetWidth - (playerCtrlProgressBarPosition.offsetWidth / 1), Math.max(8, offset));
|
||||||
|
playerCtrlProgressBarPosition.setAttribute("style", `display: block; left: ${offset}px`);
|
||||||
|
}
|
||||||
|
|
||||||
|
playerCtrlVolumeBarInteractiveArea.onmousedown = (e: MouseEvent) => { volumeChanging = true; volumeChangeMouseHandler(e) };
|
||||||
|
playerCtrlVolumeBarInteractiveArea.onmouseup = () => { volumeChanging = false; };
|
||||||
|
playerCtrlVolumeBarInteractiveArea.onmouseenter = (e: MouseEvent) => {
|
||||||
|
if (e.buttons === 0) {
|
||||||
|
scrubbing = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
playerCtrlVolumeBarInteractiveArea.onmousemove = (e: MouseEvent) => { volumeChangeMouseHandler(e) };
|
||||||
|
playerCtrlVolumeBarInteractiveArea.onwheel = (e: WheelEvent) => {
|
||||||
|
const delta = -e.deltaY;
|
||||||
|
|
||||||
|
if (delta > 0 ) {
|
||||||
|
volumeChangeHandler(Math.min(player.getVolume() + volumeIncrement, 1));
|
||||||
|
} else if (delta < 0) {
|
||||||
|
volumeChangeHandler(Math.max(player.getVolume() - volumeIncrement, 0));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function volumeChangeMouseHandler(e: MouseEvent) {
|
||||||
|
if (volumeChanging && e.buttons === 1) {
|
||||||
|
const volumeBarOffsetX = e.offsetX - 8;
|
||||||
|
const volumeBarWidth = playerCtrlVolumeBarInteractiveArea.offsetWidth - 16;
|
||||||
|
const volume = volumeBarOffsetX / volumeBarWidth;
|
||||||
|
volumeChangeHandler(volume);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function volumeChangeHandler(volume: number) {
|
||||||
|
if (!player.isMuted() && volume <= 0) {
|
||||||
|
player.setMute(true);
|
||||||
|
}
|
||||||
|
else if (player.isMuted() && volume > 0) {
|
||||||
|
player.setMute(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
player.setVolume(volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
playerCtrlLiveBadge.onclick = () => {
|
||||||
|
if (!isLivePosition) {
|
||||||
|
isLivePosition = true;
|
||||||
|
|
||||||
|
player.setCurrentTime(player.getDuration() - livePositionDelta);
|
||||||
|
playerCtrlLiveBadge.setAttribute("style", `background-color: red`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
playerCtrlCaptions.onclick = () => { player.enableCaptions(!player.isCaptionsEnabled()); playerCtrlStateUpdate(PlayerControlEvent.SetCaptions); };
|
||||||
|
playerCtrlSpeed.onclick = () => { playerCtrlStateUpdate(PlayerControlEvent.ToggleSpeedMenu); };
|
||||||
|
playerCtrlFullscreen.onclick = () => { playerCtrlStateUpdate(PlayerControlEvent.ToggleFullscreen); };
|
||||||
|
|
||||||
|
playbackRates.forEach(r => {
|
||||||
|
const entry = document.getElementById(`speedMenuEntry_${r}`);
|
||||||
|
entry.onclick = () => { player.setPlaybackRate(parseFloat(r)); playerCtrlStateUpdate(PlayerControlEvent.SetPlaybackRate); };
|
||||||
|
});
|
||||||
|
|
||||||
|
videoElement.onclick = () => {
|
||||||
|
if (player.isPaused()) {
|
||||||
|
playerCtrlStateUpdate(PlayerControlEvent.Play);
|
||||||
|
} else {
|
||||||
|
playerCtrlStateUpdate(PlayerControlEvent.Pause);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
videoElement.ondblclick = () => { playerCtrlStateUpdate(PlayerControlEvent.ToggleFullscreen); };
|
||||||
|
|
||||||
|
// Component hiding
|
||||||
|
let uiHideTimer = null;
|
||||||
|
let uiVisible = true;
|
||||||
|
|
||||||
|
function startUiHideTimer() {
|
||||||
|
uiHideTimer = window.setTimeout(() => {
|
||||||
|
uiHideTimer = null;
|
||||||
|
uiVisible = false;
|
||||||
|
playerCtrlStateUpdate(PlayerControlEvent.UiFadeOut);
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function stopUiHideTimer() {
|
||||||
|
if (uiHideTimer) {
|
||||||
|
window.clearTimeout(uiHideTimer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!uiVisible) {
|
||||||
|
uiVisible = true;
|
||||||
|
playerCtrlStateUpdate(PlayerControlEvent.UiFadeIn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.onmousemove = function() {
|
||||||
|
stopUiHideTimer();
|
||||||
|
|
||||||
|
if (player && !player.isPaused()) {
|
||||||
|
startUiHideTimer();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
window.onresize = () => { playerCtrlStateUpdate(PlayerControlEvent.TimeUpdate); };
|
||||||
|
|
||||||
|
// Add the keydown event listener to the document
|
||||||
|
const skipInterval = 10;
|
||||||
|
const volumeIncrement = 0.1;
|
||||||
|
|
||||||
|
document.addEventListener('keydown', (event) => {
|
||||||
|
console.log("KeyDown", event);
|
||||||
|
|
||||||
|
switch (event.code) {
|
||||||
|
case 'F11':
|
||||||
|
playerCtrlStateUpdate(PlayerControlEvent.ToggleFullscreen);
|
||||||
|
event.preventDefault();
|
||||||
|
break;
|
||||||
|
case 'Escape':
|
||||||
|
playerCtrlStateUpdate(PlayerControlEvent.ExitFullscreen);
|
||||||
|
event.preventDefault();
|
||||||
|
break;
|
||||||
|
case 'ArrowLeft':
|
||||||
|
// Skip back
|
||||||
|
player.setCurrentTime(Math.max(player.getCurrentTime() - skipInterval, 0));
|
||||||
|
event.preventDefault();
|
||||||
|
break;
|
||||||
|
case 'ArrowRight': {
|
||||||
|
// Skip forward
|
||||||
|
const duration = player.getDuration();
|
||||||
|
if (duration) {
|
||||||
|
player.setCurrentTime(Math.min(player.getCurrentTime() + skipInterval, duration));
|
||||||
|
} else {
|
||||||
|
player.setCurrentTime(player.getCurrentTime());
|
||||||
|
}
|
||||||
|
event.preventDefault();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'Space':
|
||||||
|
case 'Enter':
|
||||||
|
// Pause/Continue
|
||||||
|
if (player.isPaused()) {
|
||||||
|
playerCtrlStateUpdate(PlayerControlEvent.Play);
|
||||||
|
} else {
|
||||||
|
playerCtrlStateUpdate(PlayerControlEvent.Pause);
|
||||||
|
}
|
||||||
|
event.preventDefault();
|
||||||
|
break;
|
||||||
|
case 'KeyM':
|
||||||
|
// Mute toggle
|
||||||
|
playerCtrlStateUpdate(PlayerControlEvent.ToggleMute);
|
||||||
|
break;
|
||||||
|
case 'ArrowUp':
|
||||||
|
// Volume up
|
||||||
|
volumeChangeHandler(Math.min(player.getVolume() + volumeIncrement, 1));
|
||||||
|
break;
|
||||||
|
case 'ArrowDown':
|
||||||
|
// Volume down
|
||||||
|
volumeChangeHandler(Math.max(player.getVolume() - volumeIncrement, 0));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
|
@ -1,21 +1,88 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<link href="./video-js.min.css" rel="stylesheet">
|
<link rel="stylesheet" href="../../assets/fonts/inter/inter.css" />
|
||||||
<link rel="stylesheet" href="./style.css" />
|
<link rel="stylesheet" href="./style.css" />
|
||||||
<title>FCast Receiver</title>
|
<title>FCast Receiver</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<video id="video-player" class="video-js" controls preload="auto" data-setup='{}'>
|
<video id="videoPlayer" autoplay preload="auto"></video>
|
||||||
<p class="vjs-no-js">
|
<div id="videoCaptions" class="captionsContainer"></div>
|
||||||
To view this video please enable JavaScript, and consider upgrading to a web browser that
|
|
||||||
<a href="https://videojs.com/html5-video-support/" target="_blank">supports HTML5 video
|
<div id="controls" class="container">
|
||||||
</a>
|
<div class="progressBarContainer">
|
||||||
</p>
|
<div id="progressBar" ref="progressBar" class="progressBar" ></div>
|
||||||
</video>
|
<div id="progressBarBuffer" class="progressBarBuffer" ></div>
|
||||||
<script>window.HELP_IMPROVE_VIDEOJS = false;</script>
|
<div id="progressBarProgress" class="progressBarProgress" ></div>
|
||||||
<script src="./video.min.js"></script>
|
<div id="progressBarPosition" class="progressBarPosition" ></div>
|
||||||
<script src="./renderer.js"></script>
|
<!-- <div class="progressBarChapterContainer"></div> -->
|
||||||
|
<div id="progressBarHandle" class="progressBarHandle" ></div>
|
||||||
|
<div id="progressBarInteractiveArea" class="progressBarInteractiveArea" ></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="leftButtonContainer">
|
||||||
|
<div id="action" class="play"></div>
|
||||||
|
|
||||||
|
<div id="volume" class="volume_high"></div>
|
||||||
|
<div class="volumeContainer">
|
||||||
|
<div id="volumeBar" ref="volumeBar" class="volumeBar" ></div>
|
||||||
|
<div id="volumeBarProgress" class="volumeBarProgress" ></div>
|
||||||
|
<div id="volumeBarHandle" class="volumeBarHandle" ></div>
|
||||||
|
<div id="volumeBarInteractiveArea" class="volumeBarInteractiveArea" ></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="positionContainer">
|
||||||
|
<div id="liveBadge" class="liveBadge" style="display: none">LIVE</div>
|
||||||
|
<div id="position" class="position">00:00</div>
|
||||||
|
<div id="duration" class="duration">/  00:00</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="buttonContainer">
|
||||||
|
<div id="fullscreen" class="fullscreen_on"></div>
|
||||||
|
<div id="speed" class="speed"></div>
|
||||||
|
<div id="captions" class="captions_off"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="speedMenu" class="speedMenu" style="display: none">
|
||||||
|
<div class="speedMenuTitle">Playback speed</div>
|
||||||
|
<div class="speedMenuSeparator"></div>
|
||||||
|
<div id="speedMenuEntry_0.25" class="speedMenuEntry">
|
||||||
|
<div id="speedMenuEntry_0.25_enabled" class="speedMenuEntryEnabled"></div>
|
||||||
|
<div class="speedMenuEntryText">0.25</div>
|
||||||
|
</div>
|
||||||
|
<div id="speedMenuEntry_0.50" class="speedMenuEntry">
|
||||||
|
<div id="speedMenuEntry_0.50_enabled" class="speedMenuEntryEnabled"></div>
|
||||||
|
<div class="speedMenuEntryText">0.5</div>
|
||||||
|
</div>
|
||||||
|
<div id="speedMenuEntry_0.75" class="speedMenuEntry">
|
||||||
|
<div id="speedMenuEntry_0.75_enabled" class="speedMenuEntryEnabled"></div>
|
||||||
|
<div class="speedMenuEntryText">0.75</div>
|
||||||
|
</div>
|
||||||
|
<div id="speedMenuEntry_1.00" class="speedMenuEntry">
|
||||||
|
<div id="speedMenuEntry_1.00_enabled" class="speedMenuEntryEnabled"></div>
|
||||||
|
<div class="speedMenuEntryText">1.0</div>
|
||||||
|
</div>
|
||||||
|
<div id="speedMenuEntry_1.25" class="speedMenuEntry">
|
||||||
|
<div id="speedMenuEntry_1.25_enabled" class="speedMenuEntryEnabled"></div>
|
||||||
|
<div class="speedMenuEntryText">1.25</div>
|
||||||
|
</div>
|
||||||
|
<div id="speedMenuEntry_1.50" class="speedMenuEntry">
|
||||||
|
<div id="speedMenuEntry_1.50_enabled" class="speedMenuEntryEnabled"></div>
|
||||||
|
<div class="speedMenuEntryText">1.5</div>
|
||||||
|
</div>
|
||||||
|
<div id="speedMenuEntry_1.75" class="speedMenuEntry">
|
||||||
|
<div id="speedMenuEntry_1.75_enabled" class="speedMenuEntryEnabled"></div>
|
||||||
|
<div class="speedMenuEntryText">1.75</div>
|
||||||
|
</div>
|
||||||
|
<div id="speedMenuEntry_2.00" class="speedMenuEntry">
|
||||||
|
<div id="speedMenuEntry_2.00_enabled" class="speedMenuEntryEnabled"></div>
|
||||||
|
<div class="speedMenuEntryText">2.0</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="./renderer.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -1,15 +0,0 @@
|
||||||
const { contextBridge, ipcRenderer } = require('electron');
|
|
||||||
|
|
||||||
contextBridge.exposeInMainWorld('electronAPI', {
|
|
||||||
toggleFullScreen: () => ipcRenderer.send('toggle-full-screen'),
|
|
||||||
exitFullScreen: () => ipcRenderer.send('exit-full-screen'),
|
|
||||||
sendPlaybackError: (error) => ipcRenderer.send('send-playback-error', error),
|
|
||||||
sendPlaybackUpdate: (update) => ipcRenderer.send('send-playback-update', update),
|
|
||||||
sendVolumeUpdate: (update) => ipcRenderer.send('send-volume-update', update),
|
|
||||||
onPlay: (callback) => ipcRenderer.on("play", callback),
|
|
||||||
onPause: (callback) => ipcRenderer.on("pause", callback),
|
|
||||||
onResume: (callback) => ipcRenderer.on("resume", callback),
|
|
||||||
onSeek: (callback) => ipcRenderer.on("seek", callback),
|
|
||||||
onSetVolume: (callback) => ipcRenderer.on("setvolume", callback),
|
|
||||||
onSetSpeed: (callback) => ipcRenderer.on("setspeed", callback)
|
|
||||||
});
|
|
|
@ -1,240 +0,0 @@
|
||||||
function toggleFullScreen(ev) {
|
|
||||||
window.electronAPI.toggleFullScreen();
|
|
||||||
}
|
|
||||||
|
|
||||||
const options = {
|
|
||||||
textTrackSettings: false
|
|
||||||
};
|
|
||||||
|
|
||||||
let customHeaders = null;
|
|
||||||
videojs.Vhs.xhr.beforeRequest = function(options) {
|
|
||||||
options.headers = { ... options.headers, ... customHeaders };
|
|
||||||
return options;
|
|
||||||
};
|
|
||||||
|
|
||||||
const player = videojs("video-player", options, function onPlayerReady() {
|
|
||||||
const fullScreenControls = document.getElementsByClassName("vjs-fullscreen-control");
|
|
||||||
for (let i = 0; i < fullScreenControls.length; i++) {
|
|
||||||
const node = fullScreenControls[i].cloneNode(true);
|
|
||||||
fullScreenControls[i].parentNode.replaceChild(node, fullScreenControls[i]);
|
|
||||||
fullScreenControls[i].onclick = toggleFullScreen;
|
|
||||||
fullScreenControls[i].ontap = toggleFullScreen;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
sendPlaybackUpdate = (message) => {
|
|
||||||
const sanitizedMessage = {
|
|
||||||
generationTime: Date.now(),
|
|
||||||
time: message.time ? message.time : 0,
|
|
||||||
duration: message.duration && isFinite(message.duration) ? message.duration : 0,
|
|
||||||
state: message.state,
|
|
||||||
speed: message.speed ? message.speed : 1
|
|
||||||
};
|
|
||||||
|
|
||||||
window.electronAPI.sendPlaybackUpdate(sanitizedMessage);
|
|
||||||
};
|
|
||||||
|
|
||||||
player.on("pause", () => { sendPlaybackUpdate({
|
|
||||||
time: player.currentTime(),
|
|
||||||
duration: player.duration(),
|
|
||||||
state: 2,
|
|
||||||
speed: player.playbackRate()
|
|
||||||
})});
|
|
||||||
|
|
||||||
player.on("play", () => { sendPlaybackUpdate({
|
|
||||||
time: player.currentTime(),
|
|
||||||
duration: player.duration(),
|
|
||||||
state: 1,
|
|
||||||
speed: player.playbackRate()
|
|
||||||
})});
|
|
||||||
|
|
||||||
player.on("seeked", () => { sendPlaybackUpdate({
|
|
||||||
time: player.currentTime(),
|
|
||||||
duration: player.duration(),
|
|
||||||
state: player.paused() ? 2 : 1,
|
|
||||||
speed: player.playbackRate()
|
|
||||||
})});
|
|
||||||
|
|
||||||
player.on("ratechange", () => { sendPlaybackUpdate({
|
|
||||||
time: player.currentTime(),
|
|
||||||
duration: player.duration(),
|
|
||||||
state: player.paused() ? 2 : 1,
|
|
||||||
speed: player.playbackRate()
|
|
||||||
})});
|
|
||||||
|
|
||||||
player.on("volumechange", () => { window.electronAPI.sendVolumeUpdate({
|
|
||||||
generationTime: Date.now(),
|
|
||||||
volume: player.volume()
|
|
||||||
})});
|
|
||||||
|
|
||||||
player.on('error', () => { window.electronAPI.sendPlaybackError({
|
|
||||||
message: JSON.stringify(player.error())
|
|
||||||
})});
|
|
||||||
|
|
||||||
window.electronAPI.onPlay((_event, value) => {
|
|
||||||
console.log("Handle play message renderer", value);
|
|
||||||
customHeaders = value.headers;
|
|
||||||
|
|
||||||
if (value.content) {
|
|
||||||
player.src({ type: value.container, src: `data:${value.container};base64,` + window.btoa(value.content) });
|
|
||||||
} else {
|
|
||||||
player.src({ type: value.container, src: value.url });
|
|
||||||
}
|
|
||||||
|
|
||||||
const onLoadedMetadata = () => {
|
|
||||||
if (value.time) {
|
|
||||||
player.currentTime(value.time);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value.speed) {
|
|
||||||
player.playbackRate(value.speed);
|
|
||||||
} else {
|
|
||||||
player.playbackRate(1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
player.off('loadedmetadata', onLoadedMetadata);
|
|
||||||
};
|
|
||||||
|
|
||||||
player.on('loadedmetadata', onLoadedMetadata);
|
|
||||||
player.play();
|
|
||||||
});
|
|
||||||
|
|
||||||
window.electronAPI.onPause((_event) => {
|
|
||||||
console.log("Handle pause");
|
|
||||||
player.pause();
|
|
||||||
});
|
|
||||||
|
|
||||||
window.electronAPI.onResume((_event) => {
|
|
||||||
console.log("Handle resume");
|
|
||||||
player.play();
|
|
||||||
});
|
|
||||||
|
|
||||||
window.electronAPI.onSeek((_event, value) => {
|
|
||||||
console.log("Handle seek");
|
|
||||||
player.currentTime(value.time);
|
|
||||||
});
|
|
||||||
|
|
||||||
window.electronAPI.onSetVolume((_event, value) => {
|
|
||||||
console.log("Handle setVolume");
|
|
||||||
player.volume(Math.min(1.0, Math.max(0.0, value.volume)));
|
|
||||||
});
|
|
||||||
|
|
||||||
window.electronAPI.onSetSpeed((_event, value) => {
|
|
||||||
console.log("Handle setSpeed");
|
|
||||||
player.playbackRate(value.speed);
|
|
||||||
});
|
|
||||||
|
|
||||||
setInterval(() => {
|
|
||||||
sendPlaybackUpdate({
|
|
||||||
time: player.currentTime(),
|
|
||||||
duration: player.duration(),
|
|
||||||
state: player.paused() ? 2 : 1,
|
|
||||||
speed: player.playbackRate(),
|
|
||||||
});
|
|
||||||
}, 1000);
|
|
||||||
|
|
||||||
let mouseTimer = null;
|
|
||||||
let cursorVisible = true;
|
|
||||||
|
|
||||||
//Hide mouse cursor
|
|
||||||
|
|
||||||
function startMouseHideTimer() {
|
|
||||||
mouseTimer = window.setTimeout(() => {
|
|
||||||
mouseTimer = null;
|
|
||||||
document.body.style.cursor = "none";
|
|
||||||
cursorVisible = false;
|
|
||||||
}, 3000);
|
|
||||||
}
|
|
||||||
|
|
||||||
document.onmousemove = function() {
|
|
||||||
if (mouseTimer) {
|
|
||||||
window.clearTimeout(mouseTimer);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!cursorVisible) {
|
|
||||||
document.body.style.cursor = "default";
|
|
||||||
cursorVisible = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
startMouseHideTimer();
|
|
||||||
};
|
|
||||||
|
|
||||||
startMouseHideTimer();
|
|
||||||
|
|
||||||
// Add the keydown event listener to the document
|
|
||||||
const skipInterval = 10;
|
|
||||||
const volumeIncrement = 0.1;
|
|
||||||
|
|
||||||
document.addEventListener('keydown', (event) => {
|
|
||||||
console.log("KeyDown", event);
|
|
||||||
|
|
||||||
switch (event.code) {
|
|
||||||
case 'F11':
|
|
||||||
window.electronAPI.toggleFullScreen();
|
|
||||||
event.preventDefault();
|
|
||||||
break;
|
|
||||||
case 'Escape':
|
|
||||||
window.electronAPI.exitFullScreen();
|
|
||||||
event.preventDefault();
|
|
||||||
break;
|
|
||||||
case 'ArrowLeft':
|
|
||||||
// Skip back
|
|
||||||
player.currentTime(Math.max(player.currentTime() - skipInterval, 0));
|
|
||||||
event.preventDefault();
|
|
||||||
break;
|
|
||||||
case 'ArrowRight':
|
|
||||||
// Skip forward
|
|
||||||
const duration = player.duration();
|
|
||||||
if (duration) {
|
|
||||||
player.currentTime(Math.min(player.currentTime() + skipInterval, duration));
|
|
||||||
} else {
|
|
||||||
player.currentTime(player.currentTime());
|
|
||||||
}
|
|
||||||
event.preventDefault();
|
|
||||||
break;
|
|
||||||
case 'Space':
|
|
||||||
case 'Enter':
|
|
||||||
// Pause/Continue
|
|
||||||
if (player.paused()) {
|
|
||||||
player.play();
|
|
||||||
} else {
|
|
||||||
player.pause();
|
|
||||||
}
|
|
||||||
event.preventDefault();
|
|
||||||
break;
|
|
||||||
case 'KeyM':
|
|
||||||
// Mute toggle
|
|
||||||
player.muted(!player.muted());
|
|
||||||
break;
|
|
||||||
case 'ArrowUp':
|
|
||||||
// Volume up
|
|
||||||
player.volume(Math.min(player.volume() + volumeIncrement, 1));
|
|
||||||
break;
|
|
||||||
case 'ArrowDown':
|
|
||||||
// Volume down
|
|
||||||
player.volume(Math.max(player.volume() - volumeIncrement, 0));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
//Select subtitle track by default
|
|
||||||
player.ready(() => {
|
|
||||||
const textTracks = player.textTracks();
|
|
||||||
textTracks.addEventListener("change", function () {
|
|
||||||
console.log("Text tracks changed", textTracks);
|
|
||||||
for (let i = 0; i < textTracks.length; i++) {
|
|
||||||
if (textTracks[i].language === "df" && textTracks[i].mode !== "showing") {
|
|
||||||
textTracks[i].mode = "showing";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
player.on('loadedmetadata', function () {
|
|
||||||
console.log("Metadata loaded", textTracks);
|
|
||||||
for (let i = 0; i < textTracks.length; i++) {
|
|
||||||
if (textTracks[i].language === "df" && textTracks[i].mode !== "showing") {
|
|
||||||
textTracks[i].mode = "showing";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -5,9 +5,9 @@ html {
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
background-color: black;
|
background-color: black;
|
||||||
color: white;
|
color: white;
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
@ -15,7 +15,7 @@ body {
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
#video-player {
|
#videoPlayer {
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
@ -24,4 +24,475 @@ body {
|
||||||
*:focus {
|
*:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0px;
|
||||||
|
|
||||||
|
/* height: 100%; */
|
||||||
|
height: 120px;
|
||||||
|
width: 100%;
|
||||||
|
/* background: linear-gradient(to top, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0) 100%); */
|
||||||
|
background: linear-gradient(to top, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.0) 35%);
|
||||||
|
|
||||||
|
background-size: 100% 300px;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: bottom;
|
||||||
|
|
||||||
|
opacity: 1;
|
||||||
|
transition: opacity 0.1s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.volumeContainer {
|
||||||
|
position: relative;
|
||||||
|
height: 24px;
|
||||||
|
width: 92px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.volumeBar {
|
||||||
|
position: absolute;
|
||||||
|
/* left: 12px; */
|
||||||
|
left: 8px;
|
||||||
|
top: 10px;
|
||||||
|
height: 4px;
|
||||||
|
/* width: 72px; */
|
||||||
|
width: 76px;
|
||||||
|
background-color: #999999;
|
||||||
|
border-radius: 3px;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.volumeBarInteractiveArea {
|
||||||
|
position: absolute;
|
||||||
|
left: 0px;
|
||||||
|
/* left: 8px; */
|
||||||
|
top: 0px;
|
||||||
|
height: 24px;
|
||||||
|
width: 92px;
|
||||||
|
/* width: 84px; */
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.volumeBarHandle {
|
||||||
|
position: absolute;
|
||||||
|
left: 84px;
|
||||||
|
top: 4px;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
/* background-color: #ffffff; */
|
||||||
|
background-color: #c9c9c9;
|
||||||
|
box-shadow: 0px 32px 64px 0px rgba(0, 0, 0, 0.56), 0px 2px 21px 0px rgba(0, 0, 0, 0.55);
|
||||||
|
border-radius: 50%;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.volumeBarProgress {
|
||||||
|
position: absolute;
|
||||||
|
/* left: 12px; */
|
||||||
|
left: 8px;
|
||||||
|
top: 10px;
|
||||||
|
height: 4px;
|
||||||
|
width: 76px;
|
||||||
|
/* background-color: #ffffff; */
|
||||||
|
background-color: #c9c9c9;
|
||||||
|
border-radius: 3px;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progressBarContainer {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 60px;
|
||||||
|
left: 16px;
|
||||||
|
right: 16px;
|
||||||
|
height: 4px;
|
||||||
|
padding-top: 10px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
border-radius: 3px;
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progressBarInteractiveArea {
|
||||||
|
position: absolute;
|
||||||
|
/* bottom: 60px; */
|
||||||
|
/* left: 24px; */
|
||||||
|
/* right: 24px; */
|
||||||
|
height: 4px;
|
||||||
|
width: 100%;
|
||||||
|
left: 0px;
|
||||||
|
bottom: 0px;
|
||||||
|
|
||||||
|
padding-top: 10px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
border-radius: 3px;
|
||||||
|
cursor: pointer;
|
||||||
|
z-index: 999;
|
||||||
|
}
|
||||||
|
.progressBarChapterContainer {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 73px;
|
||||||
|
left: 24px;
|
||||||
|
right: 24px;
|
||||||
|
height: 4px;
|
||||||
|
border-radius: 3px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progressBar {
|
||||||
|
/* position: absolute; */
|
||||||
|
position: relative;
|
||||||
|
/* bottom: 70px; */
|
||||||
|
/* left: 24px; */
|
||||||
|
/* right: 24px; */
|
||||||
|
left: 8px;
|
||||||
|
width: calc(100% - 16px);
|
||||||
|
height: 4px;
|
||||||
|
background-color: #99999945;
|
||||||
|
border-radius: 3px;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progressBarBuffer {
|
||||||
|
/* position: absolute; */
|
||||||
|
position: relative;
|
||||||
|
/* bottom: 70px; */
|
||||||
|
/* left: 24px; */
|
||||||
|
left: 8px;
|
||||||
|
bottom: 4px;
|
||||||
|
height: 4px;
|
||||||
|
background-color: #D9D9D945;
|
||||||
|
border-radius: 3px;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progressBarProgress {
|
||||||
|
/* position: absolute; */
|
||||||
|
position: relative;
|
||||||
|
/* bottom: 70px; */
|
||||||
|
/* left: 24px; */
|
||||||
|
left: 8px;
|
||||||
|
bottom: 8px;
|
||||||
|
height: 4px;
|
||||||
|
width: 0px;
|
||||||
|
background-color: #019BE7;
|
||||||
|
border-radius: 3px;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progressBarPosition {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 25px;
|
||||||
|
padding: 2px 5px;
|
||||||
|
|
||||||
|
font-family: InterVariable;
|
||||||
|
font-size: 16px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
|
||||||
|
border-radius: 3px;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.progressBarHandle {
|
||||||
|
position: absolute;
|
||||||
|
/* bottom: 70px; */
|
||||||
|
bottom: 10px;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
margin-left: -8px;
|
||||||
|
margin-bottom: -8px;
|
||||||
|
background-color: #019BE7;
|
||||||
|
border-radius: 50%;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.positionContainer {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-grow: 1;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
font-family: InterVariable;
|
||||||
|
font-size: 16px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
|
||||||
|
user-select: text;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.position {
|
||||||
|
margin-right: 10px;
|
||||||
|
vertical-align: bottom;
|
||||||
|
|
||||||
|
color: #c9c9c9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.duration {
|
||||||
|
opacity: 0.6;
|
||||||
|
|
||||||
|
color: #c9c9c9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.liveBadge {
|
||||||
|
background-color: red;
|
||||||
|
/* margin-top: -2px; */
|
||||||
|
/* padding: 5px 5px; */
|
||||||
|
padding: 2px 5px;
|
||||||
|
border-radius: 4px;
|
||||||
|
/* margin-left: 10px; */
|
||||||
|
margin-right: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.play {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
cursor: pointer;
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
|
background-image: url("../../assets/icons/player/icon24_play.svg");
|
||||||
|
transition: background-image 0.1s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.play:hover {
|
||||||
|
background-image: url("../../assets/icons/player/icon24_play_active.svg");
|
||||||
|
}
|
||||||
|
|
||||||
|
.pause {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
cursor: pointer;
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
|
background-image: url("../../assets/icons/player/icon24_pause.svg");
|
||||||
|
transition: background-image 0.1s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pause:hover {
|
||||||
|
background-image: url("../../assets/icons/player/icon24_pause_active.svg");
|
||||||
|
}
|
||||||
|
|
||||||
|
.volume_high {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
cursor: pointer;
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
|
background-image: url("../../assets/icons/player/icon24_volume_more_50pct.svg");
|
||||||
|
transition: background-image 0.1s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.volume_high:hover {
|
||||||
|
background-image: url("../../assets/icons/player/icon24_volume_more_50pct_active.svg");
|
||||||
|
}
|
||||||
|
|
||||||
|
.volume_low {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
cursor: pointer;
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
|
background-image: url("../../assets/icons/player/icon24_volume_less_50pct.svg");
|
||||||
|
transition: background-image 0.1s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.volume_low:hover {
|
||||||
|
background-image: url("../../assets/icons/player/icon24_volume_less_50pct_active.svg");
|
||||||
|
}
|
||||||
|
|
||||||
|
.mute {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
cursor: pointer;
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
|
background-image: url("../../assets/icons/player/icon24_mute.svg");
|
||||||
|
transition: background-image 0.1s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mute:hover {
|
||||||
|
background-image: url("../../assets/icons/player/icon24_mute_active.svg");
|
||||||
|
}
|
||||||
|
|
||||||
|
.fullscreen_on {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
background-image: url("../../assets/icons/player/icon24_fullscreen_on.svg");
|
||||||
|
transition: background-image 0.1s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fullscreen_on:hover {
|
||||||
|
background-image: url("../../assets/icons/player/icon24_fullscreen_on_active.svg");
|
||||||
|
}
|
||||||
|
|
||||||
|
.fullscreen_off {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
background-image: url("../../assets/icons/player/icon24_fullscreen_off.svg");
|
||||||
|
transition: background-image 0.1s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fullscreen_off:hover {
|
||||||
|
background-image: url("../../assets/icons/player/icon24_fullscreen_off_active.svg");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.speed {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
background-image: url("../../assets/icons/player/icon24_speed.svg");
|
||||||
|
transition: background-image 0.1s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.speed:hover {
|
||||||
|
background-image: url("../../assets/icons/player/icon24_speed_active.svg");
|
||||||
|
}
|
||||||
|
|
||||||
|
.captions_off {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
background-image: url("../../assets/icons/player/icon24_cc_off.svg");
|
||||||
|
transition: background-image 0.1s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.captions_off:hover {
|
||||||
|
background-image: url("../../assets/icons/player/icon24_cc_off_active.svg");
|
||||||
|
}
|
||||||
|
|
||||||
|
.captions_on {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
background-image: url("../../assets/icons/player/icon24_cc_on.svg");
|
||||||
|
transition: background-image 0.1s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.captions_on:hover {
|
||||||
|
background-image: url("../../assets/icons/player/icon24_cc_on_active.svg");
|
||||||
|
}
|
||||||
|
|
||||||
|
.leftButtonContainer {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 24px;
|
||||||
|
left: 24px;
|
||||||
|
height: 24px;
|
||||||
|
/* width: calc(50% - 24px); */
|
||||||
|
right: 160px;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
gap: 24px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.buttonContainer {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 24px;
|
||||||
|
right: 24px;
|
||||||
|
height: 24px;
|
||||||
|
/* width: calc(50% - 24px); */
|
||||||
|
align-items: center;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
gap: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.captionsContainer {
|
||||||
|
/* display: none; */
|
||||||
|
position: relative;
|
||||||
|
/* top: -200px; */
|
||||||
|
bottom: 150px;
|
||||||
|
/* margin: auto; */
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
font-family: InterVariable;
|
||||||
|
font-size: 24px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
margin: 0px 40px 0px 40px;
|
||||||
|
|
||||||
|
|
||||||
|
/* display: flex; */
|
||||||
|
/* align-items: center; */
|
||||||
|
/* min-width: 100%; */
|
||||||
|
/* height: 100px; */
|
||||||
|
/* text-overflow: ellipsis; */
|
||||||
|
/* overflow: hidden; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.speedMenu {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 80px;
|
||||||
|
right: 60px;
|
||||||
|
height: calc(55vh);
|
||||||
|
max-height: 368px;
|
||||||
|
|
||||||
|
background-color: #141414;
|
||||||
|
padding: 12px;
|
||||||
|
border-radius: 10px;
|
||||||
|
border: 1px solid #2E2E2E;
|
||||||
|
scrollbar-width: thin;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
font-family: InterVariable;
|
||||||
|
font-size: 16px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
|
||||||
|
box-shadow: 0px 1.852px 3.148px 0px rgba(0, 0, 0, 0.06), 0px 8.148px 6.519px 0px rgba(0, 0, 0, 0.10), 0px 20px 13px 0px rgba(0, 0, 0, 0.13), 0px 38.519px 25.481px 0px rgba(0, 0, 0, 0.15), 0px 64.815px 46.852px 0px rgba(0, 0, 0, 0.19), 0px 100px 80px 0px rgba(0, 0, 0, 0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
.speedMenuTitle {
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 24px;
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.speedMenuEntry {
|
||||||
|
display: flex;
|
||||||
|
padding: 10px 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.speedMenuEntry:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: rgba(255, 255, 255, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.speedMenuSeparator {
|
||||||
|
height: 1px;
|
||||||
|
background: #2E2E2E;
|
||||||
|
margin-top: 3px;
|
||||||
|
margin-bottom: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.speedMenuEntryEnabled {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
margin-right: 10px;
|
||||||
|
|
||||||
|
background-image: url("../../assets/icons/player/icon24_check_thin.svg");
|
||||||
|
background-size: cover;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
26
receivers/electron/src/player/video.min.js
vendored
|
@ -5,6 +5,7 @@
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"sourceMap": false,
|
"sourceMap": false,
|
||||||
"emitDecoratorMetadata": true,
|
"emitDecoratorMetadata": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
"removeComments": false,
|
"removeComments": false,
|
||||||
"noImplicitAny": false,
|
"noImplicitAny": false,
|
||||||
|
|
|
@ -1,23 +1,73 @@
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = [
|
||||||
mode: 'development',
|
{
|
||||||
entry: './src/App.ts',
|
mode: 'development',
|
||||||
target: 'electron-main',
|
entry: './src/App.ts',
|
||||||
module: {
|
target: 'electron-main',
|
||||||
rules: [
|
module: {
|
||||||
{
|
rules: [
|
||||||
test: /\.tsx?$/,
|
{
|
||||||
include: /src/,
|
test: /\.tsx?$/,
|
||||||
use: [{ loader: 'ts-loader' }]
|
include: /src/,
|
||||||
}
|
use: [{ loader: 'ts-loader' }]
|
||||||
],
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
extensions: ['.tsx', '.ts', '.js'],
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
filename: 'bundle.js',
|
||||||
|
path: path.resolve(__dirname, 'dist'),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
resolve: {
|
{
|
||||||
extensions: ['.tsx', '.ts', '.js'],
|
mode: 'development',
|
||||||
|
entry: {
|
||||||
|
preload: './src/main/Preload.ts',
|
||||||
|
renderer: './src/main/Renderer.ts',
|
||||||
|
},
|
||||||
|
target: 'electron-renderer',
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.tsx?$/,
|
||||||
|
include: /src/,
|
||||||
|
use: [{ loader: 'ts-loader' }]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
extensions: ['.tsx', '.ts', '.js'],
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
filename: '[name].js',
|
||||||
|
path: path.resolve(__dirname, 'dist/main'),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
output: {
|
{
|
||||||
filename: 'bundle.js',
|
mode: 'development',
|
||||||
path: path.resolve(__dirname, 'dist'),
|
entry: {
|
||||||
},
|
preload: './src/player/Preload.ts',
|
||||||
};
|
renderer: './src/player/Renderer.ts',
|
||||||
|
},
|
||||||
|
target: 'electron-renderer',
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.tsx?$/,
|
||||||
|
include: /src/,
|
||||||
|
use: [{ loader: 'ts-loader' }]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
extensions: ['.tsx', '.ts', '.js'],
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
filename: '[name].js',
|
||||||
|
path: path.resolve(__dirname, 'dist/player'),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
];
|