NewN_UAVPlane/Assets/Plugins/WebGL/AVProVideo.jslib

609 lines
17 KiB
JavaScript

var AVProVideoWebGL = {
/*isNumber: function (item) {
return typeof(item) === "number" && !isNaN(item);
},
assert: function (equality, message) {
if (!equality)
console.log(message);
},*/
count: 0,
videos: [],
hasVideos__deps: ["videos"],
hasVideos: function (videoIndex) {
if (videoIndex) {
if (videoIndex == -1) {
return false;
}
if (_videos) {
if (_videos[videoIndex]) {
return true;
}
}
} else {
if (_videos) {
if (_videos.length > 0) {
return true;
}
}
}
return false;
},
AVPPlayerInsertVideoElement__deps: ["count", "videos"],
AVPPlayerInsertVideoElement: function (path, idValues, externalLibrary) {
if (!path) {
return false;
}
// NOTE: When loading from the indexedDB (Application.persistantDataPath),
// URL.createObjectURL() must be used get a valid URL. See:
// http://www.misfitgeek.com/html5-off-line-storing-and-retrieving-videos-with-indexeddb/
path = Pointer_stringify(path);
_count++;
var vid = document.createElement("video");
var useNativeSrcPath = true;
if (externalLibrary == 1)
{
useNativeSrcPath = false;
var player = dashjs.MediaPlayer().create();
player.initialize(vid, path, true);
}
else if (externalLibrary == 2)
{
useNativeSrcPath = false;
var hls = new Hls();
hls.loadSource(path);
hls.attachMedia(vid);
hls.on(Hls.Events.MANIFEST_PARSED,function()
{
//video.play();
});
}
else if (externalLibrary == 3)
{
//useNativeSrcPath = false;
}
// Some sources say that this is the proper way to catch errors...
/*vid.addEventListener('error', function(event) {
console.log("Error: " + event);
}, true);*/
var hasSetCanPlay = false;
var playerIndex;
var id = _count;
var vidData = {
id: id,
video: vid,
ready: false,
hasMetadata: false,
isStalled: false,
buffering: false,
lastErrorCode: 0
};
_videos.push(vidData);
playerIndex = (_videos.length > 0) ? _videos.length - 1 : 0;
vid.oncanplay = function () {
if (!hasSetCanPlay) {
hasSetCanPlay = true;
vidData.ready = true;
}
//console.log("ONCANPLAY");
};
vid.onloadedmetadata = function () {
vidData.hasMetadata = true;
};
vid.oncanplaythrough = function () {
vidData.buffering = false;
//console.log("CANPLAYTHROUGH");
};
vid.onplaying = function () {
vidData.buffering = false;
vidData.isStalled = false;
//console.log("PLAYING");
};
vid.onwaiting = function () {
vidData.buffering = true;
//console.log("WAITING");
};
vid.onstalled = function () {
vidData.isStalled = true;
//console.log("STALLED");
}
/*vid.onpause = function () {
};*/
vid.onended = function () {
vidData.buffering = false;
vidData.isStalled = false;
//console.log("ENDED");
};
vid.ontimeupdate = function() {
vidData.buffering = false;
vidData.isStalled = false;
//console.log("vid current time: ", this.currentTime);
};
vid.onerror = function (texture) {
var err = "unknown error";
switch (vid.error.code) {
case 1:
err = "video loading aborted";
break;
case 2:
err = "network loading error";
break;
case 3:
err = "video decoding failed / corrupted data or unsupported codec";
break;
case 4:
err = "video not supported";
break;
}
vidData.lastErrorCode = vid.error.code;
console.log("Error: " + err + " (errorcode=" + vid.error.code + ")", "color:red;");
};
vid.crossOrigin = "anonymous";
vid.autoplay = false;
if (useNativeSrcPath)
{
vid.src = path;
}
HEAP32[(idValues>>2)] = playerIndex;
HEAP32[(idValues>>2)+1] = id;
return true;
},
AVPPlayerGetLastError__deps: ["videos", "hasVideos"],
AVPPlayerGetLastError: function(playerIndex){
if(!_hasVideos(playerIndex))
{
return 0;
}
var ret = _videos[playerIndex].lastErrorCode
_videos[playerIndex].lastErrorCode = 0;
return ret;
},
AVPPlayerFetchVideoTexture__deps: ["videos", "hasVideos"],
AVPPlayerFetchVideoTexture: function (playerIndex, texture, init) {
if (!_hasVideos(playerIndex)) {
return;
}
GLctx.bindTexture(GLctx.TEXTURE_2D, GL.textures[texture]);
if (!init)
{
GLctx.texSubImage2D(GLctx.TEXTURE_2D, 0, 0, 0, GLctx.RGBA, GLctx.UNSIGNED_BYTE, _videos[playerIndex].video);
}
else
{
GLctx.texImage2D(GLctx.TEXTURE_2D, 0, GLctx.RGBA, GLctx.RGBA, GLctx.UNSIGNED_BYTE, _videos[playerIndex].video);
}
//NB: This line causes the texture to not show unless something else is rendered (not sure why)
//GLctx.bindTexture(GLctx.TEXTURE_2D, null);
},
AVPPlayerUpdatePlayerIndex__deps: ["videos", "hasVideos"],
AVPPlayerUpdatePlayerIndex: function (id) {
var result = -1;
if (!_hasVideos()) {
return result;
}
_videos.forEach(function (currentVid, index)
{
if (currentVid != null && currentVid.id == id)
{
result = index;
}
});
return result;
},
AVPPlayerWidth__deps: ["videos", "hasVideos"],
AVPPlayerWidth: function (playerIndex) {
if (!_hasVideos(playerIndex)) {
return 0;
}
return _videos[playerIndex].video.videoWidth;
},
AVPPlayerHeight__deps: ["videos", "hasVideos"],
AVPPlayerHeight: function (playerIndex) {
if (!_hasVideos(playerIndex)) {
return 0;
}
return _videos[playerIndex].video.videoHeight;
},
AVPPlayerReady__deps: ["videos", "hasVideos"],
AVPPlayerReady: function (playerIndex) {
if (!_hasVideos(playerIndex)) {
return false;
}
if (_videos) {
if (_videos.length > 0) {
if (_videos[playerIndex]) {
return _videos[playerIndex].ready;
}
}
} else {
return false;
}
//return _videos[playerIndex].video.readyState >= _videos[playerIndex].video.HAVE_CURRENT_DATA;
},
AVPPlayerClose__deps: ["videos", "hasVideos"],
AVPPlayerClose: function (playerIndex) {
if (!_hasVideos(playerIndex)) {
return;
}
var vid = _videos[playerIndex].video;
vid.src = "";
vid.load();
_videos[playerIndex].video = null;
_videos[playerIndex] = null;
var allEmpty = true;
for (i = 0; i < _videos.length; i++) {
if (_videos[i] != null) {
allEmpty = false;
break;
}
}
if (allEmpty)
{
_videos = [];
}
//_videos = _videos.splice(playerIndex, 1);
// Remove from DOM
//vid.parentNode.removeChild(vid);
},
AVPPlayerSetLooping__deps: ["videos", "hasVideos"],
AVPPlayerSetLooping: function (playerIndex, loop) {
if (!_hasVideos(playerIndex)) {
return;
}
_videos[playerIndex].video.loop = loop;
},
AVPPlayerIsLooping__deps: ["videos", "hasVideos"],
AVPPlayerIsLooping: function (playerIndex) {
if (!_hasVideos(playerIndex)) {
return false;
}
return _videos[playerIndex].video.loop;
},
AVPPlayerHasMetadata__deps: ["videos", "hasVideos"],
AVPPlayerHasMetadata: function (playerIndex) {
if (!_hasVideos(playerIndex)) {
return false;
}
return (_videos[playerIndex].video.readyState >= 1);
//return _videos[playerIndex].video.hasMetadata;
},
AVPPlayerIsPlaying__deps: ["videos", "hasVideos"],
AVPPlayerIsPlaying: function (playerIndex) {
if (!_hasVideos(playerIndex)) {
return false;
}
var video = _videos[playerIndex].video;
return !(video.paused || video.ended || video.seeking || video.readyState < video.HAVE_FUTURE_DATA);
},
AVPPlayerIsSeeking__deps: ["videos", "hasVideos"],
AVPPlayerIsSeeking: function (playerIndex) {
if (!_hasVideos(playerIndex)) {
return false;
}
return _videos[playerIndex].video.seeking;
},
AVPPlayerIsPaused__deps: ["videos", "hasVideos"],
AVPPlayerIsPaused: function (playerIndex) {
if (!_hasVideos(playerIndex)) {
return false;
}
return _videos[playerIndex].video.paused;
},
AVPPlayerIsFinished__deps: ["videos", "hasVideos"],
AVPPlayerIsFinished: function (playerIndex) {
if (!_hasVideos(playerIndex)) {
return false;
}
return _videos[playerIndex].video.ended;
},
AVPPlayerIsBuffering__deps: ["videos", "hasVideos"],
AVPPlayerIsBuffering: function (playerIndex) {
if (!_hasVideos(playerIndex)) {
return false;
}
return _videos[playerIndex].buffering;
},
AVPPlayerIsPlaybackStalled__deps: ["videos", "hasVideos"],
AVPPlayerIsPlaybackStalled: function (playerIndex) {
if (!_hasVideos(playerIndex)) {
return false;
}
return _videos[playerIndex].isStalled;
},
AVPPlayerPlay__deps: ["videos", "hasVideos"],
AVPPlayerPlay: function (playerIndex) {
if (!_hasVideos(playerIndex)) {
return false;
}
// https://webkit.org/blog/7734/auto-play-policy-changes-for-macos/
// https://developers.google.com/web/updates/2017/06/play-request-was-interrupted
var playPromise = _videos[playerIndex].video.play();
if (playPromise !== undefined)
{
playPromise.then(function() {
// Automatic playback started!
// Show playing UI.
})
.catch(function(error) {
// Auto-play was prevented
// Show paused UI.
return false;
});
}
return true;
},
AVPPlayerPause__deps: ["videos", "hasVideos"],
AVPPlayerPause: function (playerIndex) {
if (!_hasVideos(playerIndex)) {
return;
}
_videos[playerIndex].video.pause();
},
AVPPlayerSeekToTime__deps: ["videos", "hasVideos"],
AVPPlayerSeekToTime: function (playerIndex, timeSec, fast) {
if (!_hasVideos(playerIndex)) {
return;
}
var vid = _videos[playerIndex].video;
if (vid.seekable && vid.seekable.length > 0) {
for (i = 0; i < vid.seekable.length; i++) {
if (timeSec >= vid.seekable.start(i) && timeSec <= vid.seekable.end(i)) {
vid.currentTime = timeSec;
return;
}
}
if (timeSec == 0) {
_videos[playerIndex].video.load();
}
}
},
AVPPlayerGetCurrentTime__deps: ["videos", "hasVideos"],
AVPPlayerGetCurrentTime: function (playerIndex) {
if (!_hasVideos(playerIndex)) {
return 0.0;
}
return _videos[playerIndex].video.currentTime;
},
AVPPlayerGetPlaybackRate__deps: ["videos", "hasVideos"],
AVPPlayerGetPlaybackRate: function (playerIndex) {
if (!_hasVideos(playerIndex)) {
return 0.0;
}
return _videos[playerIndex].video.playbackRate;
},
AVPPlayerSetPlaybackRate__deps: ["videos", "hasVideos"],
AVPPlayerSetPlaybackRate: function (playerIndex, rate) {
if (!_hasVideos(playerIndex)) {
return;
}
_videos[playerIndex].video.playbackRate = rate;
},
AVPPlayerSetMuted__deps: ["videos", "hasVideos"],
AVPPlayerSetMuted: function (playerIndex, mute) {
if (!_hasVideos(playerIndex)) {
return;
}
_videos[playerIndex].video.muted = mute;
},
AVPPlayerGetDuration__deps: ["videos", "hasVideos"],
AVPPlayerGetDuration: function (playerIndex) {
if (!_hasVideos(playerIndex)) {
return 0.0;
}
return _videos[playerIndex].video.duration;
},
AVPPlayerIsMuted__deps: ["videos", "hasVideos"],
AVPPlayerIsMuted: function (playerIndex) {
if (!_hasVideos(playerIndex)) {
return false;
}
return _videos[playerIndex].video.muted;
},
AVPPlayerSetVolume__deps: ["videos", "hasVideos"],
AVPPlayerSetVolume: function (playerIndex, volume) {
if (!_hasVideos(playerIndex)) {
return;
}
_videos[playerIndex].video.volume = volume;
},
AVPPlayerGetVolume__deps: ["videos", "hasVideos"],
AVPPlayerGetVolume: function (playerIndex) {
if (!_hasVideos(playerIndex)) {
return 0.0;
}
return _videos[playerIndex].video.volume;
},
AVPPlayerHasVideo__deps: ["videos", "hasVideos"],
AVPPlayerHasVideo: function (playerIndex) {
if (!_hasVideos(playerIndex)) {
return false;
}
var isChrome = !!window.chrome && !!window.chrome.webstore;
if(isChrome){
return Boolean(_videos[playerIndex].video.webkitVideoDecodedByteCount);
}
if(_videos[playerIndex].video.videoTracks){
return Boolean(_videos[playerIndex].video.videoTracks.length);
}
return true;
},
AVPPlayerHasAudio__deps: ["videos", "hasVideos"],
AVPPlayerHasAudio: function (playerIndex) {
if (!_hasVideos(playerIndex)) {
return false;
}
return _videos[playerIndex].video.mozHasAudio || Boolean(_videos[playerIndex].video.webkitAudioDecodedByteCount) || Boolean(_videos[playerIndex].video.audioTracks && _videos[playerIndex].video.audioTracks.length);
},
AVPPlayerAudioTrackCount__deps: ["videos", "hasVideos"],
AVPPlayerAudioTrackCount: function (playerIndex) {
if (!_hasVideos(playerIndex)) {
return 0;
}
var result = 0;
if (_videos[playerIndex].video.audioTracks)
{
result = _videos[playerIndex].video.audioTracks.length;
}
return result;
},
AVPPlayerSetAudioTrack__deps: ["videos", "hasVideos"],
AVPPlayerSetAudioTrack: function (playerIndex, trackIndex) {
if (!_hasVideos(playerIndex)) {
return;
}
if (_videos[playerIndex].video.audioTracks) {
var audioTracks = _videos[playerIndex].video.audioTracks;
for (i = 0; i < audioTracks.length; i++) {
audioTracks[i].enabled = (i == trackIndex);
}
}
},
AVPPlayerGetDecodedFrameCount__deps: ["videos", "hasVideos"],
AVPPlayerGetDecodedFrameCount: function (playerIndex) {
if (!_hasVideos(playerIndex)) {
return 0;
}
var vid = _videos[playerIndex].video;
if (vid.readyState <= HTMLMediaElement.HAVE_CURRENT_DATA) {
return 0;
}
var frameCount = 0;
if (vid.webkitDecodedFrameCount)
{
frameCount = vid.webkitDecodedFrameCount;
}
else if (vid.mozDecodedFrames)
{
frameCount = vid.mozDecodedFrames;
}
return frameCount;
},
AVPPlayerSupportedDecodedFrameCount__deps: ["videos", "hasVideos"],
AVPPlayerSupportedDecodedFrameCount: function (playerIndex) {
if (!_hasVideos(playerIndex)) {
return false;
}
var vid = _videos[playerIndex].video;
if (vid.webkitDecodedFrameCount)
{
return true;
}
else if (vid.mozDecodedFrames)
{
return true;
}
return false;
},
AVPPlayerGetNumBufferedTimeRanges__deps: ["videos", "hasVideos"],
AVPPlayerGetNumBufferedTimeRanges: function(playerIndex){
if (!_hasVideos(playerIndex)) {
return 0;
}
return _videos[playerIndex].video.buffered.length;
},
AVPPlayerGetTimeRangeStart__deps: ["videos", "hasVideos"],
AVPPlayerGetTimeRangeStart: function(playerIndex, rangeIndex){
if (!_hasVideos(playerIndex)) {
return 0.0;
}
if(rangeIndex >= _videos[playerIndex].video.buffered.length){
return 0.0;
}
return _videos[playerIndex].video.buffered.start(rangeIndex);
},
AVPPlayerGetTimeRangeEnd__deps: ["videos", "hasVideos"],
AVPPlayerGetTimeRangeEnd: function(playerIndex, rangeIndex){
if (!_hasVideos(playerIndex)) {
return 0.0;
}
if(rangeIndex >= _videos[playerIndex].video.buffered.length){
return 0.0;
}
return _videos[playerIndex].video.buffered.end(rangeIndex);
}
};
autoAddDeps(AVProVideoWebGL, 'count');
autoAddDeps(AVProVideoWebGL, 'videos');
autoAddDeps(AVProVideoWebGL, 'hasVideos');
mergeInto(LibraryManager.library, AVProVideoWebGL);