Giter Club home page Giter Club logo

ogv.js's Introduction

ogv.js

Media decoder and player for Ogg Vorbis/Opus/Theora and WebM VP8/VP9/AV1 video.

Based around libogg, libvorbis, libtheora, libopus, libvpx, libnestegg and dav1d compiled to JavaScript and WebAssembly with Emscripten.

Updates

2.0.0 - 202?-??-??

  • internal API restructuring
  • file restructuring
  • es6 only
  • updated codec library releases
    • dav1d 1.3.0
    • libvpx 1.13.1
    • ogg 1.3.5
    • opus 1.4
    • vorbis 1.3.7
    • theora git master
  • simd versions using stock source and autovectorization
  • mt+simd versions available experimentally
    • using SharedArrayBuffer requires special opt-in HTTP headers

1.8.10 - 2022-??-??

  • Bump emscripten compatibility to 3.1.17

1.8.9 - 2022-04-06

  • Bump yuv-canvas to 1.2.11, further perf improvments for frame drawing
  • Workaround gets audio working when ringer is disabled by iOS hardware switch

1.8.8 - 2022-04-04

  • Bump yuv-canvas to 1.2.10, fixes WebGL scaling bug in Netscape/macOS; adjustment to prior performance tweaks.

1.8.7 - 2022-03-29

  • Bump emscripten compatibility to 3.1.8
  • Bump Opus to 1.3.1
  • Bump yuv-canvas to 1.2.9, fixes WebGL performance regressions on some browsers
  • experimental demo/threaded.php provides a COOP-COEP-CORP environment for testing threaded decoders (top-level frame and all worker JS must opt in to COOP-COEP; CORP or CORS required for most loaded resources)

1.8.6 - 2022-01-12

  • Bump to yuv-canvas
  • Fix demo for removal of video-canvas mode

1.8.5 - 2022-01-11

  • Remove unnecessary user-agent checks
  • Remove flaky, obsolete support for faking CSS object-fit
  • Remove experimental support for streaming <canvas> into <video>

1.8.4 - 2021-07-02

  • Fix for fix for OGVLoader.base fix

1.8.3 - 2021-07-02

  • Fixes for build with emscripten 2.0.25
  • Fix for nextTick/setImmediate-style polyfill in front-end
  • Provisional fix for OGVLoader.base not working with CDNs
    • the fallback code for loading a non-local worker had been broken with WebAssembly for some time, sorry!

1.8.2 - errored out

1.8.1 - 2021-02-18

  • Fixed OGVCompat APIs to correctly return false without WebAssembly and Web Audio

1.8.0 - 2021-02-09

  • Dropping IE support and Flash audio backend
    • Updated to stream-file 0.3.0
    • Updated to audio-feeder 0.5.0
    • The old IE 10/11 support no longer works due to the Flash plugin being disabled, and so is being removed
  • Drop es6-promise shim
    • Now requires WebAssembly, which requires native Promise support
  • Build & fixes
    • Demo fixed (removed test files that are now offline)
    • Builds with emscripten 2.0.13
    • Requires latest meson from git pending a fix hitting release

See more details and history in CHANGES.md

Current status

Note that as of 2021 ogv.js works pretty nicely but may still have some packagine oddities with tools like webpack. It should work via CDNs again as of 1.8.2 if you can't or don't want to package locally, but this is not documented well yet. Improved documentation will come with the next major update & code cleanup!

Since August 2015, ogv.js can be seen in action on Wikipedia and Wikimedia Commons in Safari and IE/Edge where native Ogg and WebM playback is not available. (See technical details on MediaWiki integration.)

See also a standalone demo with performance metrics at https://brooke.vibber.net/misc/ogv.js/demo/

  • streaming: yes (with Range header)
  • seeking: yes for Ogg and WebM (with Range header)
  • color: yes
  • audio: yes, with a/v sync (requires Web Audio or Flash)
  • background threading: yes (video, audio decoders in Workers)
  • GPU accelerated drawing: yes (WebGL)
  • GPU accelerated decoding: no
  • SIMD acceleration: no
  • Web Assembly: yes (with asm.js fallback)
  • multithreaded VP8, VP9, AV1: in development (set options.threading to true; requires flags to be enabled in Firefox 65 and Chrome 72, no support yet in Safari)
  • controls: no (currently provided by demo or other UI harness)

Ogg and WebM files are fairly well supported.

Goals

Long-form goal is to create a drop-in replacement for the HTML5 video and audio tags which can be used for basic playback of Ogg Theora and Vorbis or WebM media on browsers that don't support Ogg or WebM natively.

The API isn't quite complete, but works pretty well.

Compatibility

ogv.js requires a fast JS engine with typed arrays, and Web Audio for audio playback.

The primary target browsers are (testing 360p/30fps and up):

  • Safari 6.1-12 on Mac OS X 10.7-10.14
  • Safari on iOS 10-11 64-bit

Older versions of Safari have flaky JIT compilers. IE 9 and below lack typed arrays, and IE 10/11 no longer support an audio channel since the Flash plugin was sunset.

(Note that Windows and Mac OS X can support Ogg and WebM by installing codecs or alternate browsers with built-in support, but this is not possible on iOS where all browsers are really Safari.)

Testing browsers (these support .ogv and .webm natively):

  • Firefox 65
  • Chrome 73

Package installation

Pre-built releases of ogv.js are available as .zip downloads from the GitHub releases page and through the npm package manager.

You can load the ogv.js main entry point directly in a script tag, or bundle it through whatever build process you like. The other .js files must be made available for runtime loading, together in the same directory.

ogv.js will try to auto-detect the path to its resources based on the script element that loads ogv.js or ogv-support.js. If you load ogv.js through another bundler (such as browserify or MediaWiki's ResourceLoader) you may need to override this manually before instantiating players:

  // Path to ogv-demuxer-ogg.js, ogv-worker-audio.js, etc
  OGVLoader.base = '/path/to/resources';

To fetch from npm:

npm install ogv

The distribution-ready files will appear in 'node_modules/ogv/dist'.

To load the player library into your browserify or webpack project:

var ogv = require('ogv');

// Access public classes either as ogv.OGVPlayer or just OGVPlayer.
// Your build/lint tools may be happier with ogv.OGVPlayer!
ogv.OGVLoader.base = '/path/to/resources';
var player = new ogv.OGVPlayer();

Usage

The OGVPlayer class implements a player, and supports a subset of the events, properties and methods from HTMLMediaElement and HTMLVideoElement.

  // Create a new player with the constructor
  var player = new OGVPlayer();

  // Or with options
  var player = new OGVPlayer({
	debug: true,
	debugFilter: /demuxer/
  });

  // Now treat it just like a video or audio element
  containerElement.appendChild(player);
  player.src = 'path/to/media.ogv';
  player.play();
  player.addEventListener('ended', function() {
    // ta-da!
  });

To check for compatibility before creating a player, include ogv-support.js and use the OGVCompat API:

  if (OGVCompat.supported('OGVPlayer')) {
    // go load the full player from ogv.js and instantiate stuff
  }

This will check for typed arrays, web audio, blacklisted iOS versions, and super-slow/broken JIT compilers.

If you need a URL versioning/cache-buster parameter for dynamic loading of ogv.js, you can use the OGVVersion symbol provided by ogv-support.js or the even tinier ogv-version.js:

  var script = document.createElement('script');
  script.src = 'ogv.js?version=' + encodeURIComponent(OGVVersion);
  document.querySelector('head').appendChild(script);

Distribution notes

Entry points:

  • ogv.js contains the main runtime classes, including OGVPlayer, OGVLoader, and OGVCompat.
  • ogv-support.js contains the OGVCompat class and OGVVersion symbol, useful for checking for runtime support before loading the main ogv.js.
  • ogv-version.js contains only the OGVVersion symbol.

These entry points may be loaded directly from a script element, or concatenated into a larger project, or otherwise loaded as you like.

Further code modules are loaded at runtime, which must be available with their defined names together in a directory. If the files are not hosted same-origin to the web page that includes them, you will need to set up appropriate CORS headers to allow loading of the worker JS modules.

Dynamically loaded assets:

  • ogv-worker-audio.js, ogv-worker-video.js, and *.worker.js are Worker entry points, used to run video and audio decoders in the background.
  • ogv-demuxer-ogg-wasm.js/.wasm are used in playing .ogg, .oga, and .ogv files.
  • ogv-demuxer-webm-wasm.js/.wasm are used in playing .webm files.
  • ogv-decoder-audio-vorbis-wasm.js/.wasm and ogv-decoder-audio-opus-wasm.js/.wasm are used in playing both Ogg and WebM files containing audio.
  • ogv-decoder-video-theora-wasm.js/.wasm are used in playing .ogg and .ogv video files.
  • ogv-decoder-video-vp8-wasm.js/.wasm and ogv-decoder-video-vp9-wasm.js/.wasm are used in playing .webm video files.
  • *-mt.js/.wasm are the multithreaded versions of some of the above modules. They have additional support files.

If you know you will never use particular formats or codecs you can skip bundling them; for instance if you only need to play Ogg files you don't need ogv-demuxer-webm-wasm.js or ogv-decoder-video-vp8-wasm.js which are only used for WebM.

Performance

(This section is somewhat out of date.)

As of 2015, for SD-or-less resolution basic Ogg Theora decoding speed is reliable on desktop and newer high-end mobile devices; current high-end desktops and laptops can even reach HD resolutions. Older and low-end mobile devices may have difficulty on any but audio and the lowest-resolution video files.

WebM VP8/VP9 is slower, but works pretty well at a resolution step below Theora.

AV1 is slower still, and tops out around 360p for single-threaded decoding on a fast desktop or iOS device.

Low-res targets

I've gotten acceptable performance for Vorbis audio and 160p/15fps Theora files on 32-bit iOS devices: iPhone 4s, iPod Touch 5th-gen and iPad 3. These have difficulty at 240p and above, and just won't keep up with higher resolutions.

Meanwhile, newer 64-bit iPhones and iPads are comparable to low-end laptops, and videos at 360p and often 480p play acceptably. Since 32-bit and 64-bit iOS devices have the same user-agent, a benchmark must be used to approximately test minimum CPU speed.

(On iOS, Safari performs significantly better than some alternative browsers that are unable to enable the JIT due to use of the old UIWebView API. Chrome 49 and Firefox for iOS are known to work using the newer WKWebView API internally. Again, a benchmark must be used to detect slow performance, as the browser remains otherwise compatible.)

Windows on 32-bit ARM platforms is similar... IE 11 on Windows RT 8.1 on a Surface tablet (NVidia Tegra 3) does not work (crashes IE), while Edge on Windows 10 Mobile works ok at low resolutions, having trouble starting around 240p.

In both cases, a native application looms as a possibly better alternative. See OGVKit and OgvRt projects for experiments in those directions.

Note that at these lower resolutions, Vorbis audio and Theora video decoding are about equally expensive operations -- dual-core phones and tablets should be able to eke out a little parallelism here thanks to audio and video being in separate Worker threads.

WebGL drawing acceleration

Accelerated YCbCr->RGB conversion and drawing is done using WebGL on supporting browsers, or through software CPU conversion if not. This is abstracted in the yuv-canvas package, now separately installable.

It may be possible to do further acceleration of actual decoding operations using WebGL shaders, but this could be ... tricky. WebGL is also only available on the main thread, and there are no compute shaders yet so would have to use fragment shaders.

Difficulties

Threading

Currently the video and audio codecs run in worker threads by default, while the demuxer and player logic run on the UI thread. This seems to work pretty well.

There is some overhead in extracting data out of each emscripten module's heap and in the thread-to-thread communications, but the parallelism and smoother main thread makes up for it.

Streaming download

Streaming buffering is done by chunking the requests at up to a megabyte each, using the HTTP Range header. For cross-site playback, this requires CORS setup to whitelist the Range header! Chunks are downloaded as ArrayBuffers, so a chunk must be loaded in full before demuxing or playback can start.

Old versions of Safari have a bug with Range headers which is worked around as necessary with a 'cache-busting' URL string parameter.

Seeking

Seeking is implemented via the HTTP Range: header.

For Ogg files with keyframe indices in a skeleton index, seeking is very fast. Otherwise, a bisection search is used to locate the target frame or audio position, which is very slow over the internet as it creates a lot of short-lived HTTP requests.

For WebM files with cues, efficient seeking is supported as well as of 1.1.2. WebM files without cues can be seeked in 1.5.5, but inefficiently via linear seek from the beginning. This is fine for small audio-only files, but might be improved for large files with a bisection in future.

As with chunked streaming, cross-site playback requires CORS support for the Range header.

Audio output

Audio output is handled through the AudioFeeder library, which encapsulates use of Web Audio API:

Firefox, Safari, Chrome, and Edge support the W3C Web Audio API.

IE is no longer supported; the workaround using Flash no longer works due to sunsetting of the Flash plugin.

A/V synchronization is performed on files with both audio and video, and seems to actually work. Yay!

Note that autoplay with audio doesn't work on iOS Safari due to limitations with starting audio playback from event handlers; if playback is started outside an event handler, the player will hang due to broken audio.

As of 1.1.1, muting before script-triggered playback allows things to work:

  player = new OGVPlayer();
  player.muted = true;
  player.src = 'path/to/file-with-audio.ogv';
  player.play();

You can then unmute the video in response to a touch or click handler. Alternately if audio is not required, do not include an audio track in the file.

WebM

WebM support was added in June 2015, with some major issues finally worked out in May 2016. Initial VP9 support was added in February 2017. It's pretty stable in production use at Wikipedia and is enabled by default as of October 2015.

Beware that performance of WebM VP8 is much slower than Ogg Theora, and VP9 is slightly slower still.

For best WebM decode speed, consider encoding VP8 with "profile 1" (simple deblocking filter) which will sacrifice quality modestly, mainly in high-motion scenes. When encoding with ffmpeg, this is the -profile:v 1 option to the libvpx codec.

It is also recommended to use the -slices option for VP8, or -tile-columns for VP9, to maximize ability to use multithreaded decoding when available in the future.

AV1

WebM files containing the AV1 codec are supported as of 1.6.0 (February 2019) using the dav1d decoder.

Currently this is experimental, and does not advertise support via canPlayType.

Performance is about 2-3x slower than VP8 or VP9, and may require bumping down a resolution step or two to maintain frame rate. There may be further optimizations that can be done to improve this a bit, but the best improvements will come from future improvements to WebAssembly multithreading and SIMD.

Currently AV1 in MP4 container is not supported.

Upstream library notes

We've experimented with tremor (libivorbis), an integer-only variant of libvorbis. This actually does not decode faster, but does save about 200kb off our generated JavaScript, presumably thanks to not including an encoder in the library. However on slow devices like iPod Touch 5th-generation, it makes a significant negative impact on the decode time so we've gone back to libvorbis.

The Ogg Skeleton library (libskeleton) is a bit ... unfinished and is slightly modified here.

libvpx is slightly modified to work around emscripten threading limitations in the VP8 decoder.

WebAssembly

WebAssembly (Wasm) builds are used exclusively as of 1.8.0, as Safari's Wasm support is pretty well established now and IE no longer works due to the Flash plugin deprecation.

Multithreading

Experimental multithreaded VP8, VP9, and AV1 decoding up to 4 cores is in development, requiring emscripten 1.38.27 to build.

Multithreading is used only if options.threading is true. This requires browser support for the new SharedArrayBuffer and Atomics APIs, currently available in Firefox and Chrome with experimental flags enabled.

Threading currently requires WebAssembly; JavaScript builds are possible but perform poorly.

Speedups will only be noticeable when using the "slices" or "token partitions" option for VP8 encoding, or the "tile columns" option for VP9 encoding.

If you are making a slim build and will not use the threading option, you can leave out the *-mt.* files.

Building JS components

Building ogv.js is known to work on Mac OS X and Linux (tested Fedora 29 and Ubuntu 18.10 with Meson manually updated).

  1. You will need autoconf, automake, libtool, pkg-config, meson, ninja, and node (nodejs). These can be installed through Homebrew on Mac OS X, or through distribution-specific methods on Linux. For meson, you may need a newer version than your distro packages -- install it manually with pip3 or from source.
  2. Install Emscripten; currently building with 2.0.13.
  3. git submodule update --init
  4. Run npm install to install build utilities
  5. Run make js to configure and build the libraries and the C wrapper

Building the demo

If you did all the setup above, just run make demo or make. Look in build/demo/ and enjoy!

License

libogg, libvorbis, libtheora, libopus, nestegg, libvpx, and dav1d are available under their respective licenses, and the JavaScript and C wrapper code in this repo is licensed under MIT.

Based on build scripts from https://github.com/devongovett/ogg.js

See AUTHORS.md and/or the git history for a list of contributors.

ogv.js's People

Contributors

bvibber avatar maikmerten avatar tchakabam avatar devongovett avatar velochy avatar claus avatar jdforrester avatar joshuaseward avatar adventive avatar delbeke avatar skierpage avatar therightstuff avatar

Stargazers

Robin Ury avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar cz avatar  avatar 荣顶 avatar  avatar Blaze (Balázs Galambosi) avatar Ahmet Temiz avatar 忠孝东路走九遍 avatar lucas avatar Andy Rahamin avatar  avatar Chien Tran avatar  avatar 取舍 avatar  avatar Jean Leao avatar Zhou Yeheng avatar  avatar  avatar lindowx avatar Ilya Medvedev avatar  avatar  avatar Mars avatar Crsky avatar Humble avatar Gpia avatar Joalor64 avatar 明夷居士 avatar  avatar  avatar Vitaly Kogogin avatar lmath avatar Angelo avatar kevin.song avatar 奇异果 avatar Jeremie Jarosh avatar  avatar Fabio Pedretti avatar Kuzminov Alexander avatar Anders Xiao avatar PLUTO avatar  avatar Danny Kendall avatar Nick S. B. avatar David Gonzalez avatar Bloo Alien avatar  avatar  avatar  avatar denghe avatar Fuli Wu avatar  avatar pooya Games avatar Quan Le avatar Anton Bessonov avatar Miles Egan avatar  avatar Matvey Safronov avatar Ali Rahbari avatar Chenng avatar  avatar Roman avatar Eric M. Fink avatar Ray avatar lin onetwo avatar 科瑞Krits avatar fantasticit avatar  avatar captain-hema avatar Mikkel Kirkgaard Nielsen avatar sasou avatar Erik Vavro avatar Canwdev avatar Hudson Newey avatar pedoc avatar Joohun, Maeng avatar  avatar 千江水 avatar Sergey Zakharov avatar  avatar Viniciûs Cunha avatar  avatar Jax avatar 잉여개발기 avatar Sung Jeon avatar kohalab avatar  avatar Efreak avatar Tommy D. Rossi avatar Matthew Bucci avatar Nico avatar Byoungchan Lee avatar

Watchers

xinbo avatar arpu avatar Lu Zhihe avatar Brad Jones avatar  avatar Neustradamus avatar Derk-Jan Hartman avatar Lokesh avatar Thomas Hansen avatar  avatar Cristiano Contin avatar Christopher Smith avatar Clément Vasseur avatar leeoxiang avatar zhaolei avatar Noriyuki Shimizu avatar James Cloos avatar Marc Laporte avatar Kelson avatar Viacheslav Shabelnyk avatar yejinlei avatar Patrick Reed avatar Michael Anthony avatar Kasper Kamperman avatar Joshua avatar (◕ᴥ◕) avatar Haitao Yang avatar he avatar  avatar  avatar Jesse Feng avatar Brian avatar  avatar edisno avatar jason_adobe avatar Vis avatar iDzeir avatar Micheal Kinney avatar  avatar  avatar  avatar Mark Carroll avatar  avatar Quan Le avatar  avatar  avatar  avatar

ogv.js's Issues

AudioContext creation fails sometimes in Safari

AudioContext creation when initializing a new video playback sometimes fails in Safari, especially after playing several previous videos -- get a message about running out of resources.

Possibly the old one isn't being torn down properly.

Add Flash fallback for entire decoder for old browsers

I've started some experiments using crossbridge (open source version of FlasCC, similar to emscripten but for Flash) to build the codec libs to ActionScript bytecode. if the jit in Flash performs as well as the newer JS jits then this may provide a compatible fallback for IE 6/7/8/9 which we can't target with emscripten.

Audio is super choppy

Audio is super choppy; buffers aren't kept properly full and frequently under run.

Audio doesn't play in iOS

In iOS, WebAudio must be initialized in a user-initiated event handler or it's forced to mute. Currently this doesn't happen for two reasons:

  • we play automatically (not in response to a user event)
  • we don't initialize audio until after asynchronous data input and processing comes back with the presence of an audio track (not a user input event, so it may not count)

Click to play

Currently playback starts automatically on page load; this is a poor practice especially when there's audio.

Show a thumbnail and big play button instead of starting playback automatically.

Add Flash audio shim for IE 10/11

IE 10/11 doesn't support the Web Audio API, or any clear alternative I can find.

However, on Windows 8/8.1, the Adobe Flash plugin is bundled and enabled by default -- even on ARM Windows RT -- and Flash supports a similarly flexible audio output interface.

It should be possible to rig up some kind of shim, though I suspect that Flash<->JavaScript communications are asynchronous in which case an extra buffering layer may be needed, which could complicate A/V sync.

Progressive slowdown on Internet Explorer 11

Run decoder in a Worker thread

Currently the entire decoder runs on the web page's main JavaScript context -- the browser's UI thread. Especially on slower CPUs such as ARM phones and tablets this really hurts the responsiveness of the page, and it probably hurts audio output as well.

The entire decoder should be able to run in a Worker thread pretty easily. It can handle its network input with an XHR directly, and can send ArrayBuffers of pixel & audio data back up to the web page via postMessage() with the transferrable option to avoid extra data copies.

Some files cause heap to expand during playback

With the encoder running on emscripten's default 16M heap, some files such as the 'Jarry' metro video run just fine through several minutes. Others expand the heap until they overflow it and halt the program, even within just a few seconds...

Not sure yet what's causing the extra memory usage; possibilities include:

  • it's just natural memory usage triggered by the size of the frames, packets, buffers whatever. The heap needs to be slightly bigger and we won't overflow it anymore.

or

  • something's leaking and that needs to be fixed

Add WebM (VP8) playback support

So far I've concentrated on Ogg format, but it'd be good to get WebM going as well. Should compare performance and picture quality...

This requires pulling in more C libraries: libwebm for the Matroska-based container, and libvpx for the VP8 codec. Some of these may be C++ so need to look into this in more detail.

Also note that on Commons we generally have Theora transcodes at only 480p unless the original file is smaller than that; whereas for WebM we already have 360p transcodes made. That's about 45% fewer pixels to process, which is likely going to be a big performance win on slower devices.

Start autobuffering and process headers before pushing "play"

Currently we preemptively launch an audio context even if there's no audio in the file because we have to start it in a user event handler on ios. We also can't show metadata about the file such as file & frame rate and audio sample rates until playback starts.

If we go ahead and start autobuffering, we can process up through the headers right away and then can create the appropriate resources only when actual playback begins.

Add wall-clock time to playback rate stats

Currently we're measuring decoding and buffering and drawing and all sorts of things, but we're not measuring the total wall-clock time spent from frame to frame.

Including this as well as the current "CPU time" stats would help show up issues where something we're not measuring is slowing things down.

In theory wall-clock time per frame should always sit around the target frame, but if it goes higher we know something's wrong.

Add pause/continue

Currently we can halt playback, but we can't continue it except by restarting the whole thing. It would be nice to support clean pause/continue.

Huge number of 0-delay timers fired during playback

The retooled loop isn't quite right -- we seem to be firing TONS of 0-delay timers when there's not data available yet.

This ends up 'working' most of the time because it leaves the event loop able to respond, and but it looks really wrong and can't be efficient.

It also is probably bringing up the Flash shim overhead on IE because every process() call needs a check for the audio playback state.

The timers can be seen in Chrome's "timeline" view. To save sanity, wait until file is finished buffering to start recording or it'll be flooded with I/O events.

Replace 'importer' invocation with C preprocessor

To reduce compile-time dependencies, drop the node 'importer' utility in favor of the C preprocessor for including the emscripten-generated code into the wrapper code.

This may also be a handy place for conditional compilation to support multiple JS output builds so only the smallest required one need be fetched (vorbis-only, vorbis+theoradec, and vorbis+theoraenc).

Audio sample rate is usually wrong

Web Audio API's AudioContext doesn't allow us to select the output sample rate; we have to lock to whatever it defaults to (usually 48 kHz) and resample our data as necessary.

Currently, files with lower audio sample rates are horribly distorted.

Audio sync lost after a few seconds on A5/A5X-based iOS devices

On my iPod Touch 5th-gen and iPad 3rd-gen, testing with the 160p videos, I lose audio sync after maybe 15-20 seconds.

After that it seems to be decoding video frames as fast as it can and gets ahead of the playback position, not sure why yet.

On https://brionv.com/misc/ogv.js/demo2/#file=How_Open_Access_Empowered_a_16-Year-Old_to_Make_Cancer_Breakthrough.ogv&search=open%20access&size=160p.ogv it seems to regularly drop sync around the time the interviewer asks how the kid came up with a project and what was it.

Audio-only file decodes way ahead of the proper playback position

Currently if we have a video file we drive based on an approximate video clock, but if we have an audio file we basically just decode everything as soon as it comes in, and let the buffers drain out.

This is sorely noticeable on iOS devices, where the audio's really crackly -- unless you tap into the Safari URL bar which pauses the decoding timers but leaves the audio running, and it plays smooth as silk for a while until all the already-decoded audio drains out.

We should instead only decode more audio once the buffers we've already decoded are almost empty.

Build an 'oga.js' without Theora

When loading audio-only files it might be nice to fetch a smaller JavaScript payload that doesn't link in the Theora decoder.

Audio and video are out of sync

There's currently no attempt made to synchronize audio and video output, which makes videos with talking pretty unwatchable.

Performance reporting dashboard

Devise a performance reporting dashboard -- save playback quality info (per-frame decode time, played/late frame count, browser version, presence of features). Allow manual inputting of per-browser/machine metainformation.

Dubious scaling of Tremor output

Tremor produces integer PCM samples, the rest of the code assumes float. Thus a conversion takes place in ogv-libs-mixin.js - but the scaling value doesn't make any sense and was determined by blindly stumbling around...

// FIXME: Find proper scale value, seriously
outArray[i] = HEAP32[inBuffer / 4 + i] / 9999999 ;

I would have expected a value of 32k or 64k, but those turned out to be much too small.

Quantify decode speed in Mpixels/s

To have more measurable measurements than the cute graph, show something like:

  • playback data rate in Mpixels/s (width * height * fps)
  • actual decode speed in Mpixels/s

Ideally the latter should be higher than the former, otherwise we're playing too slow. :)

Use WebGL to accelerate YUV conversion and drawing

YUV conversion and drawing of the frames to the canvas is surprisingly expensive (it's a lot of pixels to churn through); on IE 11 with profiling on I'm measuring about 25% of the CPU time spent in these areas, which is a lot on a slower CPU like an ARM tablet.

IE 11 supports WebGL, which could be used to accelerate the color conversion and drawing.

Safari does not yet support WebGL by default; it can be enabled manually on Mac OS X but can't be used on iOS at all without jailbreaking.

Mozilla Research's 'Broadway' H.264 player experiment includes a self-contained class to do just the sort of thing, which can probably be nicked directly:
https://github.com/mbebenita/Broadway/blob/master/Player/canvas.js

Encapsulate player as a reusable pseudo-HTMLMediaElement

Right now a lot of the player logic is mixed in with the Commons Media of the Day demo. This should be encapsulated along with the low-level interface into ogv.js, and expose a similar API as HTMLMediaElement (video, audio elements).

That'll make it much easier to wrap it into the player UI we use in MediaWiki TimedMediaHandler.

Audio-only files don't buffer up correctly

Currently the input-and-process loop is tied to the video framerate. As a result, audio-only files just churn through the decode as fast as possible and buffer up their entire output, then playback may or may not halt early.

Move YUV conversion out of core library

Currently the library provides decoded frames only in RGB format. The conversion is done in OgvJsOutputFrame and cannot be skipped.

The decoding library should leave the decision if and how to convert to RGB to the player application, which should know the best way how to deal with conversion (convert in JavaScript, on the GPU, not at all for grayscale display etc.).

Progress regarding this issue is visible on the color-worker branch, https://github.com/brion/ogv.js/commits/color-worker

Audio should downmix >2 channels to stereo

The Flash audio fallback is limited to playing 44.1 kHz stereo audio. Maik already put in resampling and a quick fix for mono source files, but the occasional 5.1-channel file may end up with only the first two channels being output.

A very basic downmix ability might be nice; note the standard channel order is defined up to 8 (7.1) channels: http://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-800004.3.9

Here's a sample 5.1-channel file: https://brionv.com/misc/ogv.js/demo/#file=Wikimedia_Foundation_Wikipedia_Blackout_SOPA_January_18%2C_2012.theora.ogv&search=black

If I'm reading the docs correctly, we're getting the front-left and center channels with the current code.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.