mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
317 lines
8.4 KiB
JavaScript
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();
|
|
}
|