2024-11-14 21:14:29 +04:00

317 lines
8.4 KiB
JavaScript

import "event-target-polyfill";
import {decode, encode} from "base-64";
import { VideoElementStub } from "./VideoElementStub.js"
import { MediaSourceStub, SourceBufferStub } from "./MediaSourceStub.js"
import { XMLHttpRequestStub } from "./XMLHttpRequestStub.js"
global.isJsCore = false;
if (!global.btoa) {
global.btoa = encode;
}
if (!global.atob) {
global.atob = decode;
}
if (typeof window === 'undefined') {
global.isJsCore = true;
global.navigator = {
userAgent: "Telegram"
};
global.now = function() {
return _JsCorePolyfills.performanceNow();
};
global.window = {
};
global.URL = {
};
window.webkit = {
};
window.webkit.messageHandlers = {
};
window.webkit.messageHandlers.performAction = {
};
window.webkit.messageHandlers.performAction.postMessage = function(dict) {
_JsCorePolyfills.postMessage(dict);
};
global.self.location = {
href: "http://127.0.0.1"
};
global.self.setTimeout = global.setTimeout;
global.self.setInterval = global.setInterval;
global.self.clearTimeout = global.clearTimeout;
global.self.clearInterval = global.clearTimeout;
global.self.URL = global.URL;
global.self.Date = global.Date;
}
import Hls from "hls.js";
window.bridgeObjectMap = {};
window.bridgeCallbackMap = {};
function bridgeInvokeAsync(bridgeId, className, methodName, params) {
var promiseResolve;
var promiseReject;
var result = new Promise(function(resolve, reject) {
promiseResolve = resolve;
promiseReject = reject;
});
const callbackId = window.nextInternalId;
window.nextInternalId += 1;
window.bridgeCallbackMap[callbackId] = promiseResolve;
if (window.webkit.messageHandlers) {
window.webkit.messageHandlers.performAction.postMessage({
'event': 'bridgeInvoke',
'data': {
'bridgeId': bridgeId,
'className': className,
'methodName': methodName,
'params': params,
'callbackId': callbackId
}
});
}
return result;
}
window.bridgeInvokeAsync = bridgeInvokeAsync
export function bridgeInvokeCallback(callbackId, result) {
const callback = window.bridgeCallbackMap[callbackId];
if (callback) {
callback(result);
}
}
window.nextInternalId = 0;
window.mediaSourceMap = {};
// Replace the global MediaSource with our stub
if (typeof window !== 'undefined') {
window.MediaSource = MediaSourceStub;
window.ManagedMediaSource = MediaSourceStub;
window.SourceBuffer = SourceBufferStub;
window.XMLHttpRequest = XMLHttpRequestStub;
URL.createObjectURL = function(ms) {
const url = "blob:mock-media-source:" + ms.internalId;
window.mediaSourceMap[url] = ms;
return url;
};
URL.revokeObjectURL = function(url) {
};
if (global.isJsCore) {
global.HTMLVideoElement = VideoElementStub;
global.self.MediaSource = window.MediaSource;
global.self.ManagedMediaSource = window.ManagedMediaSource;
global.self.SourceBuffer = window.SourceBuffer;
global.self.XMLHttpRequest = window.XMLHttpRequest;
global.self.HTMLVideoElement = VideoElementStub;
}
}
function postPlayerEvent(id, eventName, eventData) {
if (window.webkit && window.webkit.messageHandlers) {
window.webkit.messageHandlers.performAction.postMessage({'instanceId': id, 'event': eventName, 'data': eventData});
}
}
export class HlsPlayerInstance {
constructor(id) {
this.id = id;
this.isManifestParsed = false;
this.currentTimeUpdateTimeout = null;
this.notifySeekedOnNextStatusUpdate = false;
this.video = new VideoElementStub(this.id);
}
playerInitialize(params) {
this.video.addEventListener("playing", () => {
this.refreshPlayerStatus();
});
this.video.addEventListener("pause", () => {
this.refreshPlayerStatus();
});
this.video.addEventListener("seeking", () => {
this.refreshPlayerStatus();
});
this.video.addEventListener("waiting", () => {
this.refreshPlayerStatus();
});
this.hls = new Hls({
startLevel: 0,
testBandwidth: false,
debug: params['debug'] || true,
autoStartLoad: false,
backBufferLength: 30,
maxBufferLength: 60,
maxMaxBufferLength: 60,
maxFragLookUpTolerance: 0.001,
nudgeMaxRetry: 10000
});
this.hls.on(Hls.Events.MANIFEST_PARSED, () => {
this.isManifestParsed = true;
this.refreshPlayerStatus();
});
this.hls.on(Hls.Events.LEVEL_SWITCHED, () => {
this.refreshPlayerStatus();
});
this.hls.on(Hls.Events.LEVELS_UPDATED, () => {
this.refreshPlayerStatus();
});
this.hls.loadSource(params["urlPrefix"] + "master.m3u8");
this.hls.attachMedia(this.video);
}
playerLoad(initialLevelIndex) {
this.hls.startLevel = initialLevelIndex;
this.hls.startLoad(-1, false);
}
playerPlay() {
this.video.play();
}
playerPause() {
this.video.pause();
}
playerSetBaseRate(value) {
this.video.playbackRate = value;
}
playerSetLevel(level) {
if (level >= 0) {
this.hls.currentLevel = level;
} else {
this.hls.currentLevel = -1;
}
}
playerSetCapAutoLevel(level) {
if (level >= 0) {
this.hls.autoLevelCapping = level;
} else {
this.hls.autoLevelCapping = -1;
//this.hls.currentLevel = -1;
}
}
playerSeek(value) {
this.video.currentTime = value;
}
playerSetIsMuted(value) {
this.video.muted = value;
}
getLevels() {
var levels = [];
for (var i = 0; i < this.hls.levels.length; i++) {
var level = this.hls.levels[i];
levels.push({
'index': i,
'bitrate': level.bitrate || 0,
'width': level.width || 0,
'height': level.height || 0
});
}
return levels;
}
refreshPlayerStatus() {
var isPlaying = false;
if (!this.video.paused && !this.video.ended && this.video.readyState > 2) {
isPlaying = true;
}
postPlayerEvent(this.id, 'playerStatus', {
'isReady': this.isManifestParsed,
'isPlaying': !this.video.paused,
'rate': isPlaying ? this.video.playbackRate : 0.0,
'defaultRate': this.video.playbackRate,
'levels': this.getLevels(),
'currentLevel': this.hls.currentLevel
});
this.refreshPlayerCurrentTime();
if (isPlaying) {
if (this.currentTimeUpdateTimeout == null) {
this.currentTimeUpdateTimeout = setTimeout(() => {
this.refreshPlayerCurrentTime();
}, 200);
}
} else {
if(this.currentTimeUpdateTimeout != null){
clearTimeout(this.currentTimeUpdateTimeout);
this.currentTimeUpdateTimeout = null;
}
}
if (this.notifySeekedOnNextStatusUpdate) {
this.notifySeekedOnNextStatusUpdate = false;
this.video.notifySeeked();
}
}
playerNotifySeekedOnNextStatusUpdate() {
this.notifySeekedOnNextStatusUpdate = true;
}
refreshPlayerCurrentTime() {
postPlayerEvent(this.id, 'playerCurrentTime', {
'value': this.video.currentTime
});
this.currentTimeUpdateTimeout = setTimeout(() => {
this.refreshPlayerCurrentTime()
}, 200);
}
}
window.invokeOnLoad = function() {
postPlayerEvent(this.id, 'windowOnLoad', {
});
}
window.onload = () => {
window.invokeOnLoad();
};
window.hlsPlayer_instances = {};
window.hlsPlayer_makeInstance = function(id) {
window.hlsPlayer_instances[id] = new HlsPlayerInstance(id);
}
window.hlsPlayer_destroyInstance = function(id) {
const instance = window.hlsPlayer_instances[id];
if (instance) {
delete window.hlsPlayer_instances[id];
instance.video.pause();
instance.hls.destroy();
}
}
window.bridgeInvokeCallback = bridgeInvokeCallback;
if (global.isJsCore) {
window.onload();
}