Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Spatial audio rendering via Omnitone #181

Merged
merged 20 commits into from
Sep 9, 2019
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
55a07fc
fix: VR switches to low res. after 1 chunk on HLS
gjanblaszczyk Jun 18, 2019
c56e24c
Adds support for Spatial audio via Omnitone.
gjanblaszczyk Jul 22, 2019
7d6fd7b
adds demo example for spatial media
gjanblaszczyk Jul 22, 2019
db9fea4
updates package-lock.json file
gjanblaszczyk Jul 22, 2019
f97846f
Merge pull request #1 from gjanblaszczyk/omnitone
gjanblaszczyk Jul 23, 2019
b514054
changes projection from 360_CUBE to 360
gjanblaszczyk Aug 1, 2019
f8dbbf3
Fixes problem with audiocontext suspended
gjanblaszczyk Aug 1, 2019
d6c803d
adds z-index: -1 to the video tag element.
gjanblaszczyk Aug 20, 2019
1c90b11
Merge branch 'fix-quality-issue-on-hls' into omnitone
gjanblaszczyk Aug 20, 2019
d96a3df
resolves conflicts
gjanblaszczyk Aug 28, 2019
905dd9a
Merge branch 'master' into omnitone
gjanblaszczyk Aug 28, 2019
f0e1ed7
renames `enableOmnitone` to `omnitone`
gjanblaszczyk Aug 30, 2019
43fa8f1
makes omnitone external and doesn't include it to the build files.
gjanblaszczyk Aug 30, 2019
1cb5174
updates readme file
gjanblaszczyk Aug 30, 2019
97d4e75
Merge tag 'v1.6.1' into omnitone
gjanblaszczyk Sep 6, 2019
f155f96
converts omnitone error to the warning message.
gjanblaszczyk Sep 6, 2019
46bef97
makes omnitone library a dev dependency
gjanblaszczyk Sep 9, 2019
b7baa1f
uses a reference to the omnitone instead of importing it
gjanblaszczyk Sep 9, 2019
5b7ebdb
demo page uses external spatial example from Google
gjanblaszczyk Sep 9, 2019
5411e59
updates description for omnitone option
gjanblaszczyk Sep 9, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ Maintenance Status: Stable
- [`'EAC_LR'`](#eac_lr)
- [`player.mediainfo.projection`](#playermediainfoprojection)
- [`debug`](#debug)
- [`omnitone`](#omnitone)
- [`omnitoneOptions`](#omnitoneoptions)
- [Credits](#credits)
- [Support](#support)

Expand Down Expand Up @@ -243,13 +245,27 @@ See [`projection`](#projection) above for information of values. Note that `AUTO

Enable debug logging for this plugin

### `omnitone`

> type: `boolean`, default: `false`

Enable Omnitone library for Spatial audio rendering

### `omnitoneOptions`

> type: `object`, default: `{}`

Default options for the Omnitone library. Please check available options on https://github.com/GoogleChrome/omnitone


## Credits ##

This project is a conglomeration of a few amazing open source libraries.

* [VideoJS](http://www.videojs.com)
* [Three.js](http://threejs.org)
* [webvr-polyfill](https://github.com/borismus/webvr-polyfill)
* [Omnitone](https://googlechrome.github.io/omnitone)

## Support ##
This work is sponsored by [Brightcove](https://www.brightcove.com), [HapYak](http://corp.hapyak.com/) and [StreamShark](https://streamshark.io)
30 changes: 30 additions & 0 deletions examples/spatial.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>videojs-vr Demo</title>
<link href="../node_modules/video.js/dist/video-js.css" rel="stylesheet">
<link href="../dist/videojs-vr.css" rel="stylesheet">
</head>
<body>
<video width="640" height="300" id="videojs-vr-player" class="video-js vjs-default-skin" controls playsinline>
<source src="your-spatial-video.mp4" type="video/mp4">
gjanblaszczyk marked this conversation as resolved.
Show resolved Hide resolved
</video>
<ul>
<li><a href="../">return to main example</a></li>
</ul>
<script src="../node_modules/video.js/dist/video.js"></script>
<script src="../node_modules/omnitone/build/omnitone.js"></script>
<script src="../dist/videojs-vr.js"></script>
<script>
(function(window, videojs) {
var player = window.player = videojs('videojs-vr-player');
player.mediainfo = player.mediainfo || {};
player.mediainfo.projection = '360';

// AUTO is the default and looks at mediainfo
var vr = window.vr = player.vr({projection: 'AUTO', debug: true, forceCardboard: false, omnitone: true, omnitoneOptions: {}});
}(window, window.videojs));
</script>
</body>
</html>
1 change: 1 addition & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<li><a href="examples/eac.html">EAC video example</a></li>
<li><a href="examples/eac-lr.html">EAC LR video example</a></li>
<li><a href="examples/fluid.html">"Fluid" video size example</a></li>
<li><a href="examples/spatial.html">Spatial audio example</a></li>
</ul>
</body>
</html>
4,847 changes: 2,669 additions & 2,178 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
]
},
"dependencies": {
"omnitone": "^1.3.0",
gjanblaszczyk marked this conversation as resolved.
Show resolved Hide resolved
"@babel/runtime": "^7.5.5",
"global": "^4.4.0",
"three": "0.93.0",
Expand Down
8 changes: 7 additions & 1 deletion scripts/karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@ module.exports = function(config) {

// see https://github.com/videojs/videojs-generate-karma-config
// for options
const options = {};
const options = {
files(defaults) {
return [
'node_modules/omnitone/build/omnitone.js'
];
}
};

config = generate(config, options);

Expand Down
7 changes: 7 additions & 0 deletions scripts/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ const replace = require('./rollup-replace');
// see https://github.com/videojs/videojs-generate-rollup-config
// for options
const options = {
globals(defaults) {
Object.keys(defaults).forEach(function(type) {
gjanblaszczyk marked this conversation as resolved.
Show resolved Hide resolved
defaults[type].omnitone = 'Omnitone';
});

return defaults;
},
primedPlugins(defaults) {
return Object.assign(defaults, {replace});
},
Expand Down
64 changes: 64 additions & 0 deletions src/omnitone-controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import * as Omnitone from 'omnitone';
gjanblaszczyk marked this conversation as resolved.
Show resolved Hide resolved
import videojs from 'video.js';

/**
* This class manages ambisonic decoding and binaural rendering via Omnitone library.
*/
class OmnitoneController extends videojs.EventTarget {
/**
* Omnitone controller class.
*
* @class
* @param {AudioContext} audioContext - associated AudioContext.
* @param {HTMLVideoElement} video - vidoe tag element.
* @param {Object} options - omnitone options.
*/
constructor(audioContext, video, options) {
gjanblaszczyk marked this conversation as resolved.
Show resolved Hide resolved
super();

const settings = videojs.mergeOptions({
// Safari uses the different AAC decoder than FFMPEG. The channel order is
// The default 4ch AAC channel layout for FFMPEG AAC channel ordering.
channelMap: videojs.browser.IS_SAFARI ? [2, 0, 1, 3] : [0, 1, 2, 3],
ambisonicOrder: 1
}, options);

this.videoElementSource = audioContext.createMediaElementSource(video);
this.foaRenderer = Omnitone.createFOARenderer(audioContext, settings);

this.foaRenderer.initialize().then(() => {
if (audioContext.state === 'suspended') {
this.trigger({type: 'audiocontext-suspended'});
}
this.videoElementSource.connect(this.foaRenderer.input);
this.foaRenderer.output.connect(audioContext.destination);
this.initialized = true;
this.trigger({type: 'omnitone-ready'});
}, (error) => {
videojs.log.warn(`videojs-vr: Omnitone initializes failed with the following error: ${error})`);
});
}

/**
* Updates the rotation of the Omnitone decoder based on three.js camera matrix.
*
* @param {Camera} camera Three.js camera object
*/
update(camera) {
if (!this.initialized) {
return;
}
this.foaRenderer.setRotationMatrixFromCamera(camera.matrix);
}

/**
* Destroys the controller and does any necessary cleanup.
*/
dispose() {
this.initialized = false;
this.foaRenderer.setRenderingMode('bypass');
this.foaRenderer = null;
}
}

export default OmnitoneController;
28 changes: 26 additions & 2 deletions src/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,19 @@ import VREffect from 'three/examples/js/effects/VREffect.js';
import OrbitOrientationContols from './orbit-orientation-controls.js';
import * as utils from './utils';
import CanvasPlayerControls from './canvas-player-controls';
import OmnitoneController from './omnitone-controller';
gkatsev marked this conversation as resolved.
Show resolved Hide resolved

// import controls so they get regisetered with videojs
import './cardboard-button';
import './big-vr-play-button';

// Default options for the plugin.
const defaults = {
projection: 'AUTO',
debug: false,
omnitone: false,
forceCardboard: false,
debug: false
omnitoneOptions: {},
projection: 'AUTO'
};

const errors = {
Expand Down Expand Up @@ -530,6 +533,9 @@ void main() {
}

this.controls3d.update();
if (this.omniController) {
this.omniController.update(this.camera);
}
this.effect.render(this.scene, this.camera);

if (window.navigator.getGamepads) {
Expand Down Expand Up @@ -711,6 +717,18 @@ void main() {
this.triggerError_({code: 'web-vr-not-supported', dismiss: false});
}

if (this.options_.omnitone) {
const audiocontext = THREE.AudioContext.getContext();

this.omniController = new OmnitoneController(audiocontext, this.getVideoEl_(), this.options_.omnitoneOptions);
this.omniController.one('audiocontext-suspended', () => {
this.player.pause();
this.player.one('playing', () => {
audiocontext.resume();
});
});
}

this.on(this.player_, 'fullscreenchange', this.handleResize_);
window.addEventListener('vrdisplaypresentchange', this.handleResize_, true);
window.addEventListener('resize', this.handleResize_, true);
Expand All @@ -736,6 +754,12 @@ void main() {
return;
}

if (this.omniController) {
this.omniController.off('audiocontext-suspended');
this.omniController.dispose();
this.omniController = undefined;
}

if (this.controls3d) {
this.controls3d.dispose();
this.controls3d = null;
Expand Down