• Stars
    star
    1
  • Language
    JavaScript
  • License
    Other
  • Created almost 8 years ago
  • Updated almost 8 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Released files from https://github.com/brion/ogv.js/

ogv.js

Media decoder and player for Ogg Vorbis/Opus/Theora and (experimentally) WebM video.

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

Updates

1.2.1 - 2016-09-24

  • Performance fixed for playback of Ogg Theora with many duplicate frames ("1000fps" files from ffmpeg)
  • Report actual fps (ignoring dupe frames) for Ogg Theora
  • Delay loading when using preload="none"
  • Fix regression in IE 10 network layer

1.2.0 - 2016-09-19

  • Separated software and WebGL paths to yuv-canvas package
  • fixed regression in WebM frame rate handling
  • buffer up to 3 decoded frames for smoother playback
  • smoother audio in the face of short delays (drop late frame if next one is already decoded)
  • fixed regression in seeking non-indexed Ogg files
  • updated libvpx

1.1.3 - 2016-06-27

  • fix play-during-seek bug that interacted with video.js badly

1.1.2 - 2016-06-27

  • better a/v sync
  • muted autoplay works on iOS
  • numerous seeking-related race-condition fixes
  • more consistent performance on low-end machines
  • supports cross-domain hosting of worker and Flash audio shim
  • seeking now works in WebM as well as Ogg
  • cleaner multithreading
  • lots of little fixes

See more details and history in CHANGES.md

Current status

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://brionv.com/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
  • controls: no (currently provided by demo or other UI harness)

Ogg files are fairly well supported, but WebM is still very experimental and is disabled by default.

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 either Web Audio or Flash for audio playback.

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

  • Safari 6.1/7/8/9 on Mac OS X 10.7-10.11
  • Safari on iOS 8/9 64-bit
  • Edge on Windows 10 desktop/tablet
  • Internet Explorer 10/11 on Windows 7/8/8.1/10 (desktop/tablet)

And for lower-resolution files (testing 160p/15fps):

  • Safari on iOS 8/9 32-bit
  • Edge on Windows 10 Mobile
  • Internet Explorer 10/11 on Windows RT

Older versions of Safari have flaky JIT compilers. IE 9 and below lack typed arrays.

(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, Windows RT, or Windows 10 Mobile.)

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

  • Firefox 46
  • Chrome 50

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 and the .swf file (for audio in IE) 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, dynamicaudio.swf 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({
    enableWebM: true
  });

  // 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, audio/Flash, 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 and ogv-worker-video.js are Worker entry points, used to run video and audio decoders in the background.
  • ogv-demuxer-ogg.js is used in playing .ogg, .oga, and .ogv files.
  • ogv-demuxer-webm.js is used in playing .webm files.
  • ogv-decoder-audio-vorbis.js and ogv-decoder-audio-opus.js are used in playing both Ogg and WebM files containing audio.
  • ogv-decoder-video-theora.js is used in playing .ogg and .ogv video files.
  • ogv-decoder-video-vp8.js is used in playing .webm video files.
  • dynamicaudio.swf is the Flash audio shim, used for Internet Explorer 10/11.

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.js or ogv-decoder-video-vp8.js which are only used for WebM.

Performance

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 is much slower, and remains experimental.

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), and Edge on Windows 10 Mobile build 10166 on a Lumia 635, perform acceptably with audio and with 160p/15fps videos but have 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 eek 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

In Firefox, the 'moz-chunked-array' responseType on XHR is used to read data as ArrayBuffer chunks during download. Safari and Chrome use a 'binary string' read which requires manually converting input to ArrayBuffer chunks. In IE and Edge have an (MS-prefixed) Stream/StreamReader interface which can be used to read data on demand into ArrayBuffer objects, but it has proved problematic especially with intermediate proxies; as of 1.1.2 IE and Edge use the same chunked binary-string method as Safari and Chrome.

The Firefox and Safari/Chrome cases have been hacked up to do streaming buffering 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!

Safari has a bug with Range headers which is worked around as necessary with a 'cache-busting' URL string parameter. Hopefully this will be fixed in future versions of Mac OS X and iOS.

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.

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 or Flash depending on browser support:

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

IE doesn't support Web Audio, but does bundle the Flash player in Windows 8/8.1/RT. A small Flash shim is included here and used as a fallback -- thanks to Maik Merten for hacking some pieces together and getting this working!

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. It remains experimental, but should be fully enabled in the future once a few more bugs are worked out. Beware that performance of WebM VP8 decoding is much slower than Ogg Theora.

To enable, set enableWebM: true in your options array.

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.

Building JS components

Building ogv.js is known to work on Mac OS X and Linux (tested Ubuntu 15.04).

  1. You will need autoconf, automake, libtool, pkg-config, and node (nodejs). These can be installed through Homebrew on Mac OS X, or through distribution-specific methods on Linux.
  2. Install Emscripten; currently using the 1.34.1 SDK release for distribution builds.
  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, and libvpx 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

AudioFeeder's dynamicaudio.as and other Flash-related bits are based on code under BSD license, (c) 2010 Ben Firshman.

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

More Repositories

1

ebiten

Ebitengine - A dead simple 2D game engine for Go
Go
10,614
star
2

go-mp3

An MP3 decoder in pure Go
Go
745
star
3

go2cpp

A converter from Go to C++
Go
254
star
4

wasmserve

An HTTP server for testing Wasm
Go
243
star
5

hitsumabushi

Run Go programs (almost) everywhere
C
175
star
6

goc

A C interpreter in Go
Go
119
star
7

file2byteslice

A dead simple tool to embed a file to Go
Go
92
star
8

go-steamworks

A Steamworks SDK binding for Go
Go
89
star
9

asobiba

A Go Playground in WebAssembly
JavaScript
67
star
10

go2dotnet

A converter from Go to .NET (C#)
Go
45
star
11

bitmapfont

Package bitmapfont offers a font.Face value of some bitmap fonts
Go
45
star
12

starruby

A 2D Game Library in Ruby
C
29
star
13

stbvorbis.js

A JavaScript port of stb_vorbis.c
C
27
star
14

gopherwasm

MOVED TO https://github.com/gopherjs/gopherwasm : A wrapper for GopherJS (`gopherjs/js`) and Wasm (`syscall/js`)
Go
18
star
15

cocoa_in_go

Cocoa application written in Go
Go
17
star
16

wasm-bench

Wasm Benchmark Experiment
JavaScript
16
star
17

chinesegamefonts

Chinese fonts for games: Compressed TTF binaries based on Source Han Sans (Noto Sans CJK).
Go
16
star
18

star-chat

StarChat
JavaScript
15
star
19

otto-gopherjs

Run JavaScript on browsers via Otto converted by GopherJS
Go
13
star
20

rpgmmv

Plugins for RPG Maker MV
JavaScript
11
star
21

ebitenguidemo

[WIP] A GUI demonstration in Ebiten
Go
10
star
22

ebitenginegamejam2022

Ebitengine Game Jam 2022
Go
10
star
23

hitozuma

Super IRC Bot Hitozuma (人妻)
Ruby
9
star
24

notarize

Package notarize provides APIs for Apple application notarization
Go
9
star
25

go-jisx0208

Converts a JIS X 0208 code to a rune
Go
9
star
26

ugoki

An animation editor?
Go
8
star
27

ebitenui

[WIP] A UI library based on Ebiten
Go
8
star
28

go-eossdk

An Epic Online Services SDK binding for Go
Go
8
star
29

oklab

Package oklab provides color.Color implementations for Oklab and Oklch.
Go
8
star
30

embeddll

An experiment to embed C DLL into Go program
Go
8
star
31

starruby-samplerpg

Sample RPG of Star Ruby
7
star
32

go-memorymodule

Go port of MemoryModule
C
7
star
33

macapp

A software to create a minimal *.app directory
Go
7
star
34

hajimehoshi

6
star
35

meiro

Software to generate mazes
Go
6
star
36

ebiten-suspended

Ebiten - A Simple 2D Game Library -
C++
5
star
37

starruby-launcher

Star Ruby Launcher for Windows
Ruby
5
star
38

unagi

An RPG Editor on a modern browser
TypeScript
5
star
39

ruby-php

Let's use PHP's == operator in Ruby!
Ruby
5
star
40

go-mplus-bitmap

DEPRECATED: Use https://github.com/hajimehoshi/go-mplusbitmap
Go
5
star
41

overlay-exp

Experiment with -overlay
Go
4
star
42

gopherwalk

[WIP] A game with Gophers
Go
4
star
43

go-libtess2

WIP: Go port of Mikko's libtess2
Go
4
star
44

hajimehoshi.com

hajimehoshi.com
Go
4
star
45

sugoimaze

Ebitengine Game Jam 2024
Go
4
star
46

ebiten-book-code

Code snippets in the Ebiten book
Go
4
star
47

ebitenginegamejam2023

Ebitengine Game Jam 2023
JavaScript
4
star
48

go-mplusbitmap

NO LONGER MAINTAINED: See https://github.com/hajimehoshi/bitmapfont
Go
4
star
49

ncs

Package ncs provides color in Natural Color System
Go
4
star
50

gophermv

An RPG Maker MV client written in Go
Go
3
star
51

go2carchive

[WIP] Go to C archive
Dockerfile
3
star
52

switches

Maze Game
Go
3
star
53

starrpg

An Web Site to Create RPGs
Go
3
star
54

directx-test

DirectX Test
C++
3
star
55

boxes

A Sokoban game for Ebiten tutorials
Go
3
star
56

niwatori

Dungeon Generator
Ruby
3
star
57

exp

Experimental things
JavaScript
3
star
58

fileserver

A dead simple HTTP server to serve files
Go
3
star
59

mplus-bitmap-images

Images generated from M+ fonts (bitmap)
Go
3
star
60

kakeibo

Household accounts application working on Google App Engine
Go
3
star
61

png2compressedrgba

A converter to convert a PNG file to a compressed RGBA binary
Go
3
star
62

shrimp-old

RPG Editor
C++
2
star
63

testhtml

test
HTML
2
star
64

kaiko-old

Something great
C++
2
star
65

shrimp

A Map Editor written in C#
C#
2
star
66

vivliostyle-test

Vivliostyle test
CSS
2
star
67

star-chat-irc-bridge

StarChat IRC Bridge
Ruby
2
star
68

ikiw

Something like Wiki
Ruby
2
star
69

ncspalette

WIP
Go
2
star
70

kaiko

A 2D game library written in D?
D
2
star
71

sandbox

A sandbox for me
HTML
2
star
72

egltest

EGL test
C++
2
star
73

anki_obsolete

Helper to memorize things for me
Python
2
star
74

dojin-style

同人誌用 TeX スタイル
TeX
2
star
75

oggloop

An Ogg/Vorbis meta data parser for LOOPSTART and LOOPLENGTH as RPG Maker does
Go
2
star
76

snippets

A simple storage on Google App Engine with hash keys for small and immutable data
Go
2
star
77

kagi

A simple password generator
Go
2
star
78

baseline-test

HTML
1
star
79

canvas_test

TypeScript
1
star
80

shirokuro

Go
1
star
81

project-euler

Project Euler (http://projecteuler.net/)
Haskell
1
star
82

ebiten.pagestorage

JavaScript files generated by GopherJS for http://hajimehoshi.github.io/ebiten/
1
star
83

hajimehoshi.github.com

hajimehoshi.github.com
1
star
84

serializer-bench

Go
1
star
85

playgroundtest

Go
1
star
86

darwin-wx-test

Experimental: Go + wxWidgets in OSX
C++
1
star
87

go-vorbis

WIP - Go port of stb_vorbis (http://nothings.org/stb_vorbis/)
Go
1
star
88

binpng

Converter to an two-valued PNG image
Go
1
star