This is a submission for Telegram contest for JS Developers. Tasks description.
The application is available online.
I used Media Source API for video and Web Audio API. They are played separately and sync if one gets behind another, that usually happens when browser stops video when tab becomes invisible.
Each loaded part of live stream handled with mp4box. mp4box gets initialization and media segments for video. Also, mp4box extracts all audio samples form the chunk. Samples are decoded to PCM using opus-decoder.
Initialization segment of the first part is used when creating SourceBuffer.
Media segment is appended to SourceBuffer. Decoded audio is appended to AudioBuffer connected to AudioContext.
Before starting playback, first 3 parts (3 seconds) are buffered.
Bug is related to reading AudioSpecificConfig. ASC contains information about channel count.
I find ASC in each video/mp4 streamed from ServiceWorker. If ASC is found and equal to 0x1388, I replace it with 0x1398.
This sets channel count in ASC to 0b0011 that is 3. It works also for 0b0010 that is 2, but only left channel is played. (The silence is played on right channel)
mp4a box still contains 1 channel count.
- mp4box.js - https://github.com/gpac/mp4box.js
- opus-decoder - https://www.npmjs.com/package/opus-decoder
Based on Webogram, patched and improved. Available for everyone here: https://web.telegram.org/k/
Install dependencies with:
pnpm install
This will install all the needed dependencies.
Just run pnpm start
to start the web server and the livereload task.
Open http://localhost:8080/ in your browser.
Run node build
to build the minimized production version of the app. Copy public
folder contents to your web server.
- BigInteger.js (Unlicense)
- pako (MIT License)
- cryptography (Apache License 2.0)
- emoji-data (MIT License)
- twemoji-parser (MIT License)
- rlottie (MIT License)
- fast-png (MIT License)
- opus-recorder (BSD License)
- Prism (MIT License)
- Solid (MIT License)
- libwebp.js
- fastBlur
You are welcome in helping to minimize the impact of bugs. There are classes, binded to global context. Look through the code for certain one and just get it by its name in developer tools. Source maps are included in production build for your convenience.
- test=1: to use test DCs
- debug=1: to enable additional logging
- noSharedWorker=1: to disable Shared Worker, can be useful for debugging
- http=1: to force the use of HTTPS transport when connecting to Telegram servers
Should be applied like that: http://localhost:8080/?test=1
If you find an issue with this app or wish something to be added, let Telegram know using the Suggestions Platform.
The source code is licensed under GPL v3. License is available here.