Spaces:
Runtime error
Runtime error
| <html> | |
| <head> | |
| <title>AI Web TV 🤗</title> | |
| <link href="https://cdn.jsdelivr.net/npm/daisyui@3.1.6/dist/full.css" rel="stylesheet" type="text/css" /> | |
| <!--<link href="https://vjs.zencdn.net/8.3.0/video-js.css" rel="stylesheet" />--> | |
| <script src="/mpegts.js"></script> | |
| </head> | |
| <body | |
| x-data="app()" x-init="init()" | |
| class="fixed inset-0 bg-[rgb(0,0,0)] flex flex-col w-full items-center justify-center"> | |
| <div x-show="!enabled">this space has been disabled by its owner</div> | |
| <div | |
| x-show="enabled" | |
| class="fixed w-full z-20 top-4 px-6 font-mono text-white flex items-center justify-between space-x-1" | |
| style="text-shadow: 0px 0px 3px #000000"> | |
| <div class="text-md">🤗 AI WebTV 👉 Pick a stream: | |
| <template x-for="chan in channels"> | |
| <span | |
| class="text-lg mr-2" | |
| :class="chan.id === channel.id | |
| ? 'font-bold' | |
| : 'hover:underline opacity-60 hover:opacity-80 cursor-pointer'" | |
| x-on:click="window.location = `${window.location.origin}/?channel=${chan.id}`" | |
| x-text="chan.label"></span> | |
| </template> | |
| </div> | |
| <div class="text-xs">(<a | |
| class="" | |
| :href="channel.modelUrl" | |
| x-text="channel.model" | |
| target="_blank"></a>, <span x-text="channel.resolution"></span>)</div> | |
| </div> | |
| <div class="flex w-full"> | |
| <video id="videoElement" muted autoplay class="aspect-video w-full"></video> | |
| <!-- | |
| We probably want to display a nice logo or decoration somewhere | |
| <img src="/hf-logo.png" class="absolute mt-2 w-[16%]" /> | |
| --> | |
| </div> | |
| <script> | |
| // disable analytics (we don't use VideoJS yet anyway) | |
| window.HELP_IMPROVE_VIDEOJS = false | |
| </script> | |
| <script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script> | |
| <script src="https://cdn.tailwindcss.com?plugins=forms,typography,aspect-ratio"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/4.3.2/iframeResizer.contentWindow.min.js"></script> | |
| <!--<script src="https://vjs.zencdn.net/8.3.0/video.min.js"></script>--> | |
| <script> | |
| function app() { | |
| return { | |
| enabled: false, | |
| channels: { | |
| '1': { | |
| id: '1', | |
| label: '#legacy', | |
| url: 'https://jbilcke-hf-media-server.hf.space/live/webtv.flv', | |
| resolution: '576x320', | |
| model: 'cerspense/zeroscope_v2_576w', | |
| modelUrl: 'https://huggingface.co/cerspense/zeroscope_v2_576w', | |
| }, | |
| '2': { | |
| id: '2', | |
| label: '#HDTV', | |
| url: 'https://jbilcke-hf-media-server.hf.space/live/webtv2.flv', | |
| resolution: '1024x576', | |
| model: 'cerspense/zeroscope_v2_XL', | |
| modelUrl: 'https://huggingface.co/cerspense/zeroscope_v2_XL', | |
| }, | |
| }, | |
| defaultChannelId: '2', | |
| channel: { | |
| }, | |
| init() { | |
| console.log('initializing WebTV..') | |
| const urlParams = new URLSearchParams(window.location.search) | |
| const requestedChannelId = `${urlParams.get('channel') || ''}` | |
| this.enabled = `${urlParams.get('beta') || 'false'}` === 'true' | |
| if (!this.enabled) { | |
| return | |
| } | |
| const defaultChannel = this.channels[this.defaultChannelId] | |
| this.channel = this.channels[requestedChannelId] || defaultChannel | |
| console.log(`Selected channel: ${this.channel.label}`) | |
| console.log(`Stream URL: ${this.channel.url}`) | |
| // some devices such as the iPhone don't support MSE Live Playback | |
| if (mpegts.getFeatureList().mseLivePlayback) { | |
| var videoElement = document.getElementById('videoElement') | |
| var player = mpegts.createPlayer({ | |
| type: 'flv', // could also be mpegts, m2ts, flv | |
| isLive: true, | |
| url: this.channel.url, | |
| }) | |
| player.attachMediaElement(videoElement) | |
| player.on(mpegts.Events.ERROR, function (err) { | |
| console.log('got an error:', err) | |
| if (err.type === mpegts.ErrorTypes.NETWORK_ERROR) { | |
| console.log('Network error') | |
| } | |
| }); | |
| player.load() | |
| // due to an issue with our stream when the FFMPEG playlist ends, | |
| // the stream gets interrupted for ~1sec, which causes the frontend to hangs up | |
| // the following code tries to restart the page when that happens, but in the long term | |
| // we should fix the issue on the server side (fix our FFMPEG bash script) | |
| videoElement.addEventListener('ended', function() { | |
| console.log('Stream ended, trying to reload...') | |
| setTimeout(() => { | |
| console.log('Reloading the page..') | |
| // Unloading and loading the source again isn't enough it seems | |
| // player.unload() | |
| // player.load() | |
| window.location.reload() | |
| }, 1200) | |
| }, false) | |
| // Handle autoplay restrictions. | |
| let promise = videoElement.play() | |
| if (promise !== undefined) { | |
| videoElement.addEventListener('click', function() { | |
| videoElement.play() | |
| }) | |
| } | |
| player.play() | |
| } | |
| } | |
| } | |
| } | |
| </script> | |
| </body> | |
| </html> |