The player (odd.player.js) has been polished for years of practice. It always adheres to the goals of being professional, efficient, delicate, and easy to use. It precisely controls every frame of data, combined with perfect interfaces, events, and highly free UI frameworks to easily meet various business and Custom requirements.
api.addEventListener('ready', function(e) {
// do something
});
api.onready = function(e) {
// do something
};
var utils = odd.utils,
events = odd.events,
Event = events.Event,
IOEvent = events.IOEvent,
MediaEvent = events.MediaEvent,
SaverEvent = events.SaverEvent,
index = 0;
var api = odd.player();
api.addEventListener(Event.READY, onReady);
api.addEventListener(Event.PLAY, console.log);
api.addEventListener(IOEvent.LOADSTART, console.log);
api.addEventListener(Event.WAITING, console.log);
api.addEventListener(IOEvent.STALLED, console.log);
api.addEventListener(IOEvent.ABORT, console.log);
api.addEventListener(IOEvent.TIMEOUT, console.log);
api.addEventListener(Event.DURATIONCHANGE, console.log);
api.addEventListener(Event.LOADEDMETADATA, console.log);
api.addEventListener(Event.LOADEDDATA, console.log);
api.addEventListener(IOEvent.PROGRESS, console.log);
api.addEventListener(Event.CANPLAY, console.log);
api.addEventListener(Event.PLAYING, console.log);
api.addEventListener(Event.CANPLAYTHROUGH, console.log);
api.addEventListener(IOEvent.SUSPEND, console.log);
api.addEventListener(Event.PAUSE, console.log);
api.addEventListener(Event.SEEKING, console.log);
api.addEventListener(Event.SEEKED, console.log);
api.addEventListener(Event.SWITCHING, console.log);
api.addEventListener(Event.SWITCHED, console.log);
api.addEventListener(Event.RATECHANGE, console.log);
api.addEventListener(Event.TIMEUPDATE, console.log);
api.addEventListener(Event.VOLUMECHANGE, console.log);
api.addEventListener(IOEvent.LOAD, console.log);
api.addEventListener(MediaEvent.INFOCHANGE, console.log);
api.addEventListener(MediaEvent.STATSUPDATE, console.log);
api.addEventListener(MediaEvent.SEI, console.log);
api.addEventListener(MediaEvent.SCREENSHOT, onScreenshot);
api.addEventListener(SaverEvent.WRITERSTART, console.log);
api.addEventListener(SaverEvent.WRITEREND, console.log);
api.addEventListener(Event.ENDED, console.log);
api.addEventListener(Event.ERROR, console.error);
api.setup(container, {
file: 'http://127.0.0.1/vod/sample.flv',
});
function onReady(e) {
// ui.record('fragmented.mp4');
}
function onScreenshot(e) {
var arr = e.data.image.split(',');
var ret = arr[0].match(/^data:(image\/(.+));base64$/);
if (ret === null) {
console.error('The string did not match the expected pattern.');
return;
}
var link = document.createElement('a');
link.href = e.data.image;
link.download = 'screenshot-' + utils.padStart(index++, 3, '0') + '.' + ret[2];
link.click();
}
var events = odd.events,
Event = events.Event,
UIEvent = events.UIEvent,
MouseEvent = events.MouseEvent;
var ui = odd.player.ui(0, { mode: 'file' });
ui.addEventListener(Event.READY, onReady);
ui.addEventListener(MouseEvent.CLICK, onClick);
ui.addEventListener(UIEvent.SHOOTING, console.log);
ui.addEventListener(UIEvent.FULLPAGE, console.log);
ui.addEventListener(UIEvent.FULLSCREEN, console.log);
ui.addEventListener(UIEvent.RESIZE, console.log);
ui.setup(container, {
...
service: {
script: 'js/sw.js',
scope: 'js/',
enable: false,
},
});
function onReady(e) {
// ui.record('fragmented.mp4');
}
function onClick(e) {
switch (e.data.name) {
case 'report':
ui.logger.flush();
break;
}
}
{
airplay: 'allow',
autoplay: false,
dynamic: false, // dynamic streaming
bufferLength: 0.3, // sec.
file: '',
lowlatency: true, // ll-dash, ll-hls, ll-flv/fmp4 (auto reduce latency due to cumulative ack of tcp)
maxBufferLength: 1.2, // sec.
maxPlaybackLength: 10, // sec. for live mode only
maxRetries: 0, // maximum number of retries while some types of error occurs. -1 means always
mode: 'live', // live, vod
module: '', // SRC, FLV, FMP4, DASH, HLS, RTC, Flash
muted: false,
objectfit: 'contain', // fill, contain, cover, none, scale-down
playsinline: true,
preload: 'none', // none, metadata, auto
retrying: 0, // ms. retrying interval
smoothing: false, // smooth switching
volume: 0.8,
loader: {
name: 'auto',
mode: 'cors', // cors, no-cors, same-origin
credentials: 'omit', // omit, include, same-origin
},
rtc: {},
service: {
script: 'js/sw.js',
scope: 'js/',
enable: false,
},
sources: [{ // ignored if "file" is presented
file: '',
module: '',
label: '',
default: false,
}],
}
{
aspectratio: '', // deprecated! 16:9 etc.
client: null,
skin: 'classic',
plugins: [{
kind: 'Poster',
file: 'images/poster.png',
cors: 'anonymous', // anonymous, use-credentials
objectfit: 'fill', // fill, contain, cover, none, scale-down
visibility: true,
}, {
kind: 'Chat',
visibility: true,
}, {
kind: 'Danmu',
speed: 100,
lineHeight: 32,
enable: true,
visibility: true,
}, {
kind: 'Display',
layout: '[Button:play=][Button:waiting=][Label:error=][Panel:info=][Panel:stats=]',
ondoubleclick: 'fullscreen', // fullpage, fullscreen
visibility: true,
}, {
kind: 'AD',
visibility: true,
}, {
kind: 'Share',
visibility: true,
}, {
kind: 'Logo',
file: 'https://oddengine.com/image/odd-player-logo.png',
link: 'https://oddengine.com/product/player.html',
cors: 'anonymous', // anonymous, use-credentials
target: '_blank',
style: 'margin: 3% 5%; width: 36px; height: 36px; top: 0px; right: 0px;',
visibility: true,
}, {
kind: 'Controlbar',
layout: '[Slider:timebar=Preview]|[Button:play=Play][Button:pause=Pause][Button:reload=Reload][Button:stop=Stop][Label:quote=Live broadcast][Label:time=00:00/00:00]||[Button:report=Report][Button:capture=Capture][Button:download=Download][Button:mute=Mute][Button:unmute=Unmute][Slider:volumebar=80][Select:definition=Definition][Button:danmuoff=Danmu Off][Button:danmuon=Danmu On][Button:fullpage=Fullpage][Button:exitfullpage=Exit Fullpage][Button:fullscreen=Fullscreen][Button:exitfullscreen=Exit Fullscreen]',
autohide: false,
visibility: true,
}, {
kind: 'ContextMenu',
visibility: true,
items: [{
mode: '', // '', featured, disable
icon: 'image/github.png',
text: 'github.com',
shortcut: '',
handler: function () { window.open('https://oddengine.com/product/player.html'); },
}],
}]
};
{
level: 'log', // debug, log, warn, error
mode: 'console', // console, file, feedback
maxLines: 60,
}
Method | Arguments | Description |
---|---|---|
get | id = 0, option = undefined | Gets the API instance by id, create one if it doesn't exist. Option is the config of Logger. |
create | option = undefined | Creates an API instance with an auto-increased id, or return the one already exist. Option is the config of Logger. |
Method | Arguments | Description |
---|---|---|
setup | container, config | Setup the API with the given configuration. |
play | url = '', options = null | Plays the specified media file or live stream, or the current item of the sources if the url doesn't provided. |
pause | Pauses playing. Calling this method does nothing if the video is already paused. | |
seek | offset | Seeks the keyframe (also called an I-frame in the video industry) closest to the specified location. |
stop | Stops playing, sets the time property to 0. | |
reload | Releases all the resources, reloads the media file or live stream. | |
muted | status | Mutes or unmutes the audio/video elements, if status is a boolean. Otherwise, returns the current status. |
volume | f | Sets volume, which in the range of 0 to 1, if f is a number. Otherwise, returns the current volume. |
definition | index | Switches to the specified definition, if index is a number. Otherwise, returns the current definition. |
capture | width, height, mime | Captures the current frame, dispatches an screenshot event, and returns the image. |
record | filename | Records a stream once the ServiceWorker is activated, and returns a StreamWriter. The current writer will be closed if filename equals false. |
element | Gets the current rendering element, such as video, flash, canvas, etc. | |
getProperty | key | Gets property by key. Currently, key could be "info" and "stats". |
duration | Gets the media duration. | |
state | Gets the ready state. | |
destroy | Destroy this instance, removes dom elements. |
Method | Arguments | Description |
---|---|---|
get | id = 0, option = undefined | Gets the UI instance by id, create one if it doesn't exist. Option is the config of Logger. |
create | option = undefined | Create an UI instance with an auto-increment id, or return the one already exist. Option is the config of Logger. |
Method | Arguments | Description |
---|---|---|
setup | container, config | Setup the UI with the given configuration. |
danmu | enable | Enables or disables the danmu plugin, if enable is a boolean. Otherwise, returns the current status. |
shoot | text, data = null | Shoots the text with the data binded to. |
displayAD | element | Displays the AD element. |
removeAD | Removes the AD element. | |
fullpage | status | Requests or exits fullpage, if status is a boolean. Otherwise, returns the current status. |
fullscreen | status | Requests or exits fullscreen, if status is a boolean. Otherwise, returns the current status. |
resize | Resizes the player to fit to the parent node. | |
destroy | Destroy this instance, removes dom elements. |
Type | Properties | Meaning |
---|---|---|
READY | The ready event occurs when a module is ready. | |
PLAY | The play event occurs when it has been started or is no longer paused. | |
WAITING | The waiting event occurs when it stops because it needs to buffer the next frame. | |
DURATIONCHANGE | duration | The durationchange event occurs when the duration data is changed. |
LOADEDMETADATA | metadata | The loadedmetadata event occurs when metadata has been loaded. |
LOADEDDATA | The loadeddata event occurs when data for the current frame is loaded, but not enough data to play next frame. | |
CANPLAY | The canplay event occurs when the browser can start playing (when it has buffered enough to begin). | |
PLAYING | The playing event occurs when it is playing after having been paused or stopped for buffering. | |
CANPLAYTHROUGH | The canplaythrough event occurs when the browser estimates it can play through the specified media without having to stop for buffering. | |
PAUSE | timestamp | The pause event occurs when it is paused either by the user or programmatically. |
SEEKING | timestamp | The seeking event occurs when the user starts moving/skipping to a new position. |
SEEKED | timestamp | The seeked event occurs when the user is finished moving/skipping to a new position. |
SWITCHING | index | The switching event occurs when the user starts switching to a different definition. |
SWITCHED | index | The switching event occurs when the user is finished switching to a different definition. |
RATECHANGE | rate | The ratechange event occurs when the playing speed is changed, which is invoked by the playbackRate method. |
TIMEUPDATE | timestamp, buffered | The timeupdate event occurs when the playing position has changed. |
VOLUMECHANGE | volume | The volumechange event occurs each time the volume has been changed. |
ENDED | The ended event occurs when the media has reached the end. | |
ERROR | code, message | The error event occurs when an error occurred. |
Type | Properties | Meaning |
---|---|---|
CHANGE | name, value | The change event occurs when the value of the named target is changed. |
VISIBILITYCHANGE | name, state | The visibilitychange event occurs when the visibility of the named target is changed. The state could be "visible" "hidden". |
Type | Properties | Meaning |
---|---|---|
LOADSTART | The loadstart event occurs when the browser starts loading. | |
STALLED | The stalled event occurs when the browser is trying to get media data, but data is not available. | |
ABORT | The abort event occurs when the loading is aborted. | |
TIMEOUT | The timeout event occurs when progression is terminated due to preset time expiring. | |
PROGRESS | loaded, total, buffer | The progress event occurs when the browser is downloading. |
SUSPEND | The suspend event occurs when the browser is intentionally not getting media data. | |
LOAD | The load event occurs when an object has been loaded. | |
LOADEND | The loadend event occurs when a request has completed, whether successfully (after load) or unsuccessfully (after abort or error). |
Type | Properties | Meaning |
---|---|---|
KEY_DOWN | code, alt, control, shift, command | The keydown event occurs when the key is pressed. |
KEY_UP | code, alt, control, shift, command | The keyup event occurs when the key is released. |
Type | Properties | Meaning |
---|---|---|
INFOCHANGE | info | The infochange event occurs when the meida info is changed. |
STATSUPDATE | stats | The statsupdate event occurs when the media stats is changed. |
SEI | packet, nalu | The sei event occurs when a SEI NalUnit is detected. |
SCREENSHOT | image | The screenshot event occurs when an image is captured. |
Type | Properties | Meaning |
---|---|---|
CLICK | name, value | The click event occurs when the user clicked the named target. |
DOUBLE_CLICK | name, state | The doubleclick event occurs when the user double clicked the named target. |
MOUSE_MOVE | name, value | The mousemove event occurs when the mouse is moved upon the named target. |
Type | Properties | Meaning |
---|---|---|
TIMER | The timer event occurs when the timer clock. | |
COMPLETE | The complete event occurs when the timer is completed. |
Type | Properties | Meaning |
---|---|---|
SHOOTING | text, data | The shooting event occurs when a damnu message is shot. |
FULLPAGE | status | The fullpage event occurs when the fullpage status is changed. |
FULLSCREEN | status | The fullscreen event occurs when the fullscreen status is changed. |
RESIZE | width, height | The resize event occurs when the UI is resized. |