-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCrafyVideoJS_minified.js
1 lines (1 loc) · 30.5 KB
/
CrafyVideoJS_minified.js
1
class CrafyVideoJSWebGLImageManager { constructor(e, t) { this.targetWidth = e, this.targetHeight = t, this.initWebGL() } initWebGL() { if (this.canvas = new OffscreenCanvas(this.targetWidth, this.targetHeight), this.gl = this.canvas.getContext("webgl2"), !this.gl) throw new Error("WebGL2 no disponible"); const e = this.compileShader("#version 300 es\n in vec4 a_position;\n in vec2 a_texCoord;\n out vec2 v_texCoord;\n void main() {\n gl_Position = a_position;\n v_texCoord = vec2(a_texCoord.x, 1.0 - a_texCoord.y);\n }\n ", this.gl.VERTEX_SHADER), t = this.compileShader("#version 300 es\n precision highp float;\n uniform sampler2D u_texture;\n in vec2 v_texCoord;\n out vec4 outColor;\n void main() {\n outColor = texture(u_texture, v_texCoord);\n }\n ", this.gl.FRAGMENT_SHADER); if (this.program = this.gl.createProgram(), this.gl.attachShader(this.program, e), this.gl.attachShader(this.program, t), this.gl.linkProgram(this.program), !this.gl.getProgramParameter(this.program, this.gl.LINK_STATUS)) throw new Error("Error al linkear programa WebGL"); const i = new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]), o = new Float32Array([0, 0, 1, 0, 0, 1, 1, 1]); this.positionBuffer = this.gl.createBuffer(), this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.positionBuffer), this.gl.bufferData(this.gl.ARRAY_BUFFER, i, this.gl.STATIC_DRAW), this.texCoordBuffer = this.gl.createBuffer(), this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.texCoordBuffer), this.gl.bufferData(this.gl.ARRAY_BUFFER, o, this.gl.STATIC_DRAW), this.positionLocation = this.gl.getAttribLocation(this.program, "a_position"), this.texCoordLocation = this.gl.getAttribLocation(this.program, "a_texCoord"), this.texture = this.gl.createTexture(), this.gl.bindTexture(this.gl.TEXTURE_2D, this.texture), this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE), this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE), this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR), this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR) } compileShader(e, t) { const i = this.gl.createShader(t); if (this.gl.shaderSource(i, e), this.gl.compileShader(i), !this.gl.getShaderParameter(i, this.gl.COMPILE_STATUS)) throw new Error("Error al compilar shader: " + this.gl.getShaderInfoLog(i)); return i } async resize(e) { const t = this.gl; t.useProgram(this.program), t.viewport(0, 0, this.targetWidth, this.targetHeight), t.bindBuffer(t.ARRAY_BUFFER, this.positionBuffer), t.enableVertexAttribArray(this.positionLocation), t.vertexAttribPointer(this.positionLocation, 2, t.FLOAT, !1, 0, 0), t.bindBuffer(t.ARRAY_BUFFER, this.texCoordBuffer), t.enableVertexAttribArray(this.texCoordLocation), t.vertexAttribPointer(this.texCoordLocation, 2, t.FLOAT, !1, 0, 0), t.bindTexture(t.TEXTURE_2D, this.texture), t.texImage2D(t.TEXTURE_2D, 0, t.RGBA, t.RGBA, t.UNSIGNED_BYTE, e), t.drawArrays(t.TRIANGLE_STRIP, 0, 4), await this.waitForSync(t.fenceSync(t.SYNC_GPU_COMMANDS_COMPLETE, 0)); const i = await createImageBitmap(this.canvas), o = new VideoFrame(i, { timestamp: e.timestamp, duration: e.duration }); return i.close(), o } waitForSync(e) { return new Promise((t => { const i = () => { const o = this.gl.clientWaitSync(e, this.gl.SYNC_FLUSH_COMMANDS_BIT, 0); o === this.gl.TIMEOUT_EXPIRED ? requestAnimationFrame(i) : (this.gl.WAIT_FAILED, t()) }; i() })) } cleanup() { const e = this.gl; e.deleteProgram(this.program), e.deleteBuffer(this.positionBuffer), e.deleteBuffer(this.texCoordBuffer), e.deleteTexture(this.texture) } } class CrafyVideoJS { constructor(e = !1) { this.logs = e, this.resetThisVariables() } resetThisVariables() { this.VIDEO_TIMESCALE = 9e4, this.AUDIO_TIMESCALE = 48e3, this.AUDIO_SAMPLERATE = 48e3, this.AUDIO_SAMPLESIZE = 16, this.AUDIO_CHANNELCOUNT = 2, this.isFirstVideoSample = !0, this.chunkOffset = 40, this.itsOnError = !1 } onProgress(e) { } onError(e) { } onResult(e) { } in_onError(e) { this.itsOnError = !0, this.onError(e) } async processVideo({ file: file, start_timestamp: start_timestamp = !1, end_timestamp: end_timestamp = !1, max_video_bitrate: max_video_bitrate = !1, max_video_resolution: max_video_resolution = !1, queue_max_size: queue_max_size = 10, redimension_system: redimension_system = "bitmap", encoder_latencyMode: encoder_latencyMode = "quality", video_info_read_max_time: video_info_read_max_time = 6e4, redimension_resizeQuality: redimension_resizeQuality = "low", max_input_video_size: max_input_video_size = !1, max_input_video_samplesCount: max_input_video_samplesCount = !1, preprocess_video_info_function: preprocess_video_info_function = !1, output_video_codec: output_video_codec = "avc1", audio_queue_max_size: audio_queue_max_size = 20 } = {}) { this.resetThisVariables(); var savedThis = this; if (!1 === preprocess_video_info_function && (preprocess_video_info_function = savedThis.helper_preprocess_video_info_function), !1 !== end_timestamp && !1 === start_timestamp && (start_timestamp = 0), !1 !== start_timestamp && start_timestamp < 0 && (start_timestamp = 0), !1 !== start_timestamp && !1 !== end_timestamp && end_timestamp <= start_timestamp) throw new Error("end_timestamp must be greater than start_timestamp."); const startNow = performance.now(); let videoDecoder, videoEncoder, audioDecoder, audioEncoder; savedThis.logs && console.log("Started!"); let videoTrack = null, audioTrack = null, decodedVideoFrameIndex = 0, encodedVideoFrameIndex = 0, videoFrameCount = 0, audioFrameCount = 0, decodedAudioFrameIndex = 0, encodedAudioFrameIndex = 0, nextVideoKeyFrameTimestamp = 0, nextAudioKeyFrameTimestamp = 0, sampleVideoDurations = [], sampleAudioDurations = [], videoTrak = null, audioTrak = null, outputAudioCodec, inputVideoBitrate, inputAudioBitrate, inputVideoSamplesNumber, videoResizer, encodedFinishedPromise, encodedFinishedPromise_resolved = !1, encodedFinishedPromise_resolver, encodedAudioFinishedPromise; encodedFinishedPromise = new Promise((e => { encodedFinishedPromise_resolver = e })); let encodedAudioFinishedPromise_resolved = !1, encodedAudioFinishedPromise_resolver; encodedAudioFinishedPromise = new Promise((e => { encodedAudioFinishedPromise_resolver = e })); let audioSendedToEncodeCount = 0, mp4boxInputFileReadyPromise_resolver, mp4boxInputFileReadyPromise = new Promise((e => { mp4boxInputFileReadyPromise_resolver = e })); const mp4boxOutputFile = savedThis.createMP4File(); savedThis.glob_mp4boxOutputFile = mp4boxOutputFile; const mp4boxInputFile = MP4Box.createFile(); mp4boxInputFile.onError = e => { savedThis.logs && console.error(e) }, mp4boxInputFile.onReady = async info => { if (savedThis.logs && console.log("mp4boxInputFile info", info), videoTrack = info.videoTracks[0], audioTrack = info.audioTracks[0], audioTrack && "mp4a" == audioTrack.codec && (audioTrack.codec = "mp4a.40.2"), videoTrack && !1 !== max_input_video_samplesCount && videoTrack.nb_samples > max_input_video_samplesCount) throw new Error("exceded_max_input_video_samplesCount"); preprocess_video_info_function(info).then((preprocess_video_info_response => { if (Object.entries(preprocess_video_info_response).length > 0) for (const [variableName, variableNewValue] of Object.entries(preprocess_video_info_response)) eval(variableName + " = variableNewValue;"); audioTrack && (outputAudioCodec = audioTrack.codec), savedThis.getSupportedAudioBitrates(audioTrack, outputAudioCodec).then((e => { if (savedThis.logs && console.log("queue_max_size", queue_max_size, "audio_queue_max_size", audio_queue_max_size), videoTrack) { savedThis.VIDEO_TIMESCALE = videoTrack.timescale, inputVideoBitrate = videoTrack.bitrate, inputVideoSamplesNumber = videoTrack.nb_samples; var t = !1, i = max_video_resolution; if (!1 !== max_video_resolution && "number" != typeof max_video_resolution) if ("by_near_samplesCount" == max_video_resolution.type) i = Math.round(max_video_resolution.data[Object.keys(max_video_resolution.data)[savedThis.findClosestIndex(Object.keys(max_video_resolution.data), inputVideoSamplesNumber)]]); else if ("by_max_samplesCount" == max_video_resolution.type) { const e = Object.entries(max_video_resolution.data).sort((([e], [t]) => e.localeCompare(t))), t = Object.fromEntries(e); var o = !1; for (const [e, i] of Object.entries(t)) if (0 != e && inputVideoSamplesNumber <= e) { o = i; break } !1 !== o ? i = o : void 0 !== max_video_resolution.data[0] && (i = max_video_resolution.data[0]) } savedThis.logs && console.log("finalMaxVideoResolution", i), !1 !== i && !1 !== (t = savedThis.getDimensionsForResize(videoTrack.track_width, videoTrack.track_height, i, !0, !0)) && ("webgl" == redimension_system && (videoResizer = new CrafyVideoJSWebGLImageManager(t.width, t.height)), savedThis.logs && console.log("Video redimension", t)); var a = !0; let e; videoDecoder = new VideoDecoder({ async output(e) { var i, o = !0; if (!1 !== start_timestamp && e.timestamp < start_timestamp && (o = !1), o) if (!1 !== t) { if ("webgl" == redimension_system) i = await videoResizer.resize(e); else if ("bitmap" == redimension_system) { const o = await createImageBitmap(e, { resizeWidth: t.width, resizeHeight: t.height, resizeQuality: redimension_resizeQuality }); i = new VideoFrame(o, { timestamp: e.timestamp, duration: e.duration }), o.close() } if (a) a = !1, videoEncoder.encode(i, { keyFrame: !0, timestamp: e.timestamp }); else try { videoEncoder.encode(i, { timestamp: e.timestamp }) } catch (e) { savedThis.logs && console.error(e) } } else { const t = await createImageBitmap(e, { resizeWidth: e.codedWidth, resizeHeight: e.codedHeight, resizeQuality: redimension_resizeQuality }); i = new VideoFrame(t, { timestamp: e.timestamp, duration: e.duration }), t.close(), a ? (a = !1, videoEncoder.encode(i, { keyFrame: !0, timestamp: e.timestamp })) : videoEncoder.encode(i, { timestamp: e.timestamp }) } else videoFrameCount--; try { void 0 !== i && i.close(), e.close() } catch (e) { } decodedVideoFrameIndex++, displayProgress() }, error(e) { savedThis.logs && console.error(e) } }); const d = mp4boxInputFile.getTrackById(videoTrack.id); for (const t of d.mdia.minf.stbl.stsd.entries) if (t.avcC || t.hvcC) { const i = new DataStream(void 0, 0, DataStream.BIG_ENDIAN); t.avcC ? t.avcC.write(i) : t.hvcC.write(i), e = new Uint8Array(i.buffer, 8); break } videoDecoder.configure({ codec: videoTrack.codec, codedWidth: videoTrack.track_width, codedHeight: videoTrack.track_height, hardwareAcceleration: "prefer-hardware", description: e }); var r = { width: videoTrack.track_width, height: videoTrack.track_height }; !1 !== t && (r.width = t.width, r.height = t.height); let n = r.width * r.height, c = Math.round(inputVideoBitrate); if (!1 !== max_video_bitrate) if ("number" == typeof max_video_bitrate) c > max_video_bitrate && (c = Math.round(max_video_bitrate)); else if ("percentage_of_original" == max_video_bitrate.type) c = Math.round(c / 100 * max_video_bitrate.percentage); else if ("max_by_resolution" == max_video_bitrate.type) { let e = max_video_bitrate.data[Object.keys(max_video_bitrate.data)[savedThis.findClosestIndex(Object.keys(max_video_bitrate.data), n)]]; c > e && (c = Math.round(e)) } else if ("percentage_of_original_by_resolution" == max_video_bitrate.type) c = Math.round(c / 100 * max_video_bitrate.data[Object.keys(max_video_bitrate.data)[savedThis.findClosestIndex(Object.keys(max_video_bitrate.data), n)]]); else if ("percentage_and_max_of_original_by_resolution" == max_video_bitrate.type) { let e = max_video_bitrate.data[Object.keys(max_video_bitrate.data)[savedThis.findClosestIndex(Object.keys(max_video_bitrate.data), n)]]; c = Math.round(c / 100 * e.percentage), c > e.max && (c = Math.round(e.max)) } var s; savedThis.logs && console.log("newVideoBitrate", c), "avc1" == output_video_codec ? s = savedThis.getAVCCodec(r.width, r.height, c) : "hvc1" == output_video_codec && (s = savedThis.getHVC1Codec(r.width, r.height, c)), savedThis.logs && console.log("outputVideoCodec", s), videoEncoder = new VideoEncoder({ output(e, t) { let i = new Uint8Array(e.byteLength); if (e.copyTo(i), null === videoTrak) { let e = { type: "video", width: r.width, height: r.height, codec: s }; "avc1" == output_video_codec ? e.avcDecoderConfigRecord = t.decoderConfig.description : "hvc1" == output_video_codec && (e.hvcDecoderConfigRecord = t.decoderConfig.description, e.hevcParams = { profileSpace: 0, tierFlag: 0, profileIdc: 1, profileCompatibility: 1610612736, levelIdc: 93, constraintIndicatorFlags: new Uint8Array([144, 0, 0, 0, 0, 0]), chromaFormat: 1, bitDepth: 8 }), videoTrak = savedThis.addTrak(mp4boxOutputFile, e, output_video_codec) } const o = sampleVideoDurations.shift() / (1e6 / savedThis.VIDEO_TIMESCALE); savedThis.addSample(mp4boxOutputFile, videoTrak, i, "key" === e.type, o, !0, output_video_codec, t), encodedVideoFrameIndex++, displayProgress() }, error(e) { savedThis.logs && console.error(e), savedThis.in_onError(e) } }), savedThis.logs && console.log("videoEncoder.configure", JSON.stringify({ codec: s, width: r.width, height: r.height, hardwareAcceleration: "prefer-hardware", bitrate: c, bitrateMode: "variable", alpha: "discard", latencyMode: encoder_latencyMode })), videoEncoder.configure({ codec: s, width: r.width, height: r.height, hardwareAcceleration: "prefer-hardware", bitrate: c, bitrateMode: "variable", alpha: "discard", latencyMode: encoder_latencyMode }), mp4boxInputFile.setExtractionOptions(videoTrack.id, null, { nbSamples: 1 / 0 }) } if (audioTrack) { savedThis.AUDIO_TIMESCALE = audioTrack.timescale, savedThis.AUDIO_SAMPLERATE = audioTrack.audio.sample_rate, savedThis.AUDIO_SAMPLESIZE = audioTrack.audio.sample_size, savedThis.AUDIO_CHANNELCOUNT = audioTrack.audio.channel_count, inputAudioBitrate = audioTrack.bitrate; var d = !0; audioDecoder = new AudioDecoder({ async output(e) { if (savedThis.itsOnError) return !1; var t = !0; !1 !== start_timestamp && e.timestamp < start_timestamp && (t = !1), t ? (d ? (d = !1, audioEncoder.encode(e, { keyFrame: !0 })) : audioEncoder.encode(e), audioSendedToEncodeCount++) : audioFrameCount--, e.close(), decodedAudioFrameIndex++, displayProgress() }, error(e) { savedThis.logs && console.error(e) } }); var n = audioTrack.codec; let t; const i = mp4boxInputFile.getTrackById(audioTrack.id); for (const e of i.mdia.minf.stbl.stsd.entries) if (e.dOps) { const i = new DataStream(void 0, 0, DataStream.BIG_ENDIAN); e.dOps && e.dOps.write(i), t = new Uint8Array(i.buffer); break } var c = { codec: n, numberOfChannels: audioTrack.audio.channel_count, sampleRate: audioTrack.audio.sample_rate }; void 0 !== t && (c.description = t), audioDecoder.configure(c), audioEncoder = new AudioEncoder({ output(e, i) { let o = new Uint8Array(e.byteLength); e.copyTo(o), null === audioTrak && (audioTrak = savedThis.addTrak(mp4boxOutputFile, { type: "audio", codec: outputAudioCodec, audioAvgBitrate: l, decoderConfig_description: t }, output_video_codec)); const a = sampleAudioDurations.shift() / (1e6 / savedThis.AUDIO_TIMESCALE); savedThis.addSample(mp4boxOutputFile, audioTrak, o, "key" === e.type, a, !videoTrack), encodedAudioFrameIndex++, displayProgress() }, error(e) { savedThis.logs && console.error(e), savedThis.in_onError(e) } }), savedThis.logs && console.log("outputAudioCodec", outputAudioCodec), savedThis.logs && console.log("supportedAudioBitrates", e); var l = e[savedThis.findClosestIndex(e, Math.round(audioTrack.bitrate))]; savedThis.logs && console.log("newAudioBitrate", l), audioEncoder.configure({ codec: outputAudioCodec, numberOfChannels: audioTrack.audio.channel_count, sampleRate: audioTrack.audio.sample_rate, bitrate: Math.round(l), bitratemode: "variable" }), mp4boxInputFile.setExtractionOptions(audioTrack.id, null, { nbSamples: 1 / 0 }) } mp4boxInputFile.start(), mp4boxInputFileReadyPromise_resolver() })) })) }; var video_eta = { decoding_percentage: 0, decoding_eta: null, encoding_percentage: 0, encoding_eta: null, total_percentage: 0, total_eta: null }, groupsOfVideoChunks, groupsOfAudioChunks; function displayProgress() { var e = {}; if (videoTrack) { let t = Math.round(performance.now()) - Math.round(startNow), i = Math.round(100 * decodedVideoFrameIndex / videoFrameCount); i > video_eta.decoding_percentage && (video_eta.decoding_percentage = i, video_eta.decoding_eta = i >= 100 ? 0 : 100 * t / i - t); let o = Math.round(100 * encodedVideoFrameIndex / videoFrameCount); o > video_eta.encoding_percentage && (video_eta.encoding_percentage = o, video_eta.encoding_eta = o >= 100 ? 0 : 100 * t / o - t); let a = i + o; a > video_eta.total_percentage && (video_eta.total_percentage = a, video_eta.total_eta = a >= 200 ? 0 : 200 * t / a * 1.1 - t), e.video = { decoding: { index: decodedVideoFrameIndex, count: videoFrameCount, percentage: i, percentage_original: 100 * decodedVideoFrameIndex / videoFrameCount, eta: video_eta.decoding_eta }, encoding: { index: encodedVideoFrameIndex, count: videoFrameCount, percentage: o, percentage_original: 100 * encodedVideoFrameIndex / videoFrameCount, eta: video_eta.encoding_eta }, eta: video_eta.total_eta } } audioTrack && (e.audio = { decoding: { index: decodedAudioFrameIndex, count: audioFrameCount, percentage: Math.round(100 * decodedAudioFrameIndex / audioFrameCount), percentage_original: 100 * decodedAudioFrameIndex / audioFrameCount }, encoding: { index: encodedAudioFrameIndex, count: audioFrameCount, percentage: Math.round(100 * encodedAudioFrameIndex / audioFrameCount), percentage_original: 100 * encodedAudioFrameIndex / audioFrameCount } }), savedThis.onProgress(e) } function findNearestKeyframe(e, t, i) { const o = t * i / 1e6; let a = null; for (const t of e) if (t.is_sync) { if (a && !(t.cts <= o)) break; a = t } if (!a) throw new Error("No keyframe found before the specified startTime."); return { keyframe: a, timestamp: 1e6 * a.cts / i } } function filterFramesByRange(e, t, i, o, a) { savedThis.logs && console.log("filterFramesByRange timescale", o); const r = t * o / 1e6; var s = 1 / 0; !1 !== i && (s = i * o / 1e6), savedThis.logs && console.log("cts", r, s), savedThis.logs && console.log("keyframeCts", a); return e.filter((e => e.cts >= a && e.cts <= s)) } async function processGroupsOfVideoChunks() { for (const t of groupsOfVideoChunks) { for (const i of t) { if (savedThis.itsOnError) return !1; for (var e = !0; e;)if (videoDecoder.decodeQueueSize < queue_max_size && videoEncoder.encodeQueueSize < queue_max_size) { try { videoDecoder.decode(new EncodedVideoChunk(i)) } catch (e) { throw savedThis.in_onError(e), new Error("Decode frame error.") } e = !1 } else await sleep(1) } await videoDecoder.flush() } videoDecoder.close(); let t = !0; for (; t;)0 == videoEncoder.encodeQueueSize ? (t = !1, encodedFinishedPromise_resolved = !0, encodedFinishedPromise_resolver()) : await sleep(3) } async function processGroupsOfAudioChunks() { for (const t of groupsOfAudioChunks) { for (const i of t) { if (savedThis.itsOnError) return !1; for (var e = !0; e;)if (audioDecoder.decodeQueueSize < audio_queue_max_size && audioEncoder.encodeQueueSize < audio_queue_max_size) { try { audioDecoder.decode(new EncodedAudioChunk(i)) } catch (e) { throw savedThis.logs && console.error("Decode audio sample error.", e), savedThis.in_onError(e), new Error("Decode audio sample error.") } e = !1 } else await sleep(1) } await audioDecoder.flush() } audioDecoder.close(); let t = !0; for (; t;)0 == audioEncoder.encodeQueueSize ? (t = !1, encodedAudioFinishedPromise_resolved = !0, encodedAudioFinishedPromise_resolver()) : await sleep(3) } async function sleep(e) { return new Promise((t => setTimeout(t, e))) } function splitGroupOfVideoChunks(e) { return [e] } async function onComplete() { var e = {}; e.video_array_buffer = mp4boxOutputFile.getBuffer(); const t = (performance.now() - startNow) / 1e3; if (e.reencoding_time_seconds = t, videoTrack && (e.reencoding_video_frames = encodedVideoFrameIndex, e.reencoding_video_fps = Math.round(encodedVideoFrameIndex / t)), audioTrack && (e.reencoding_audio_frames = encodedAudioFrameIndex, e.reencoding_audio_fps = Math.round(encodedAudioFrameIndex / t)), null === videoTrack && null === audioTrack) throw new Error("Can't decodify video."); return e } mp4boxInputFile.onSamples = function (e, t, i) { if (savedThis.itsOnError) return !1; let o = i; if (!1 !== start_timestamp) { const e = findNearestKeyframe(i, start_timestamp, i[0].timescale); o = filterFramesByRange(i, start_timestamp, end_timestamp, i[0].timescale, e.keyframe.cts) } let a = [], r = []; for (const t of o) { const i = { type: t.is_sync ? "key" : "delta", timestamp: 1e6 * t.cts / t.timescale, duration: 1e6 * t.duration / t.timescale, data: t.data }; videoTrack && e === videoTrack.id ? (videoFrameCount++, sampleVideoDurations.push(1e6 * t.duration / t.timescale), a.push(i)) : audioTrack && e === audioTrack.id && (audioFrameCount++, sampleAudioDurations.push(1e6 * t.duration / t.timescale), r.push(i)) } o = null, a.length > 0 && (groupsOfVideoChunks = splitGroupOfVideoChunks(a), processGroupsOfVideoChunks()), r.length > 0 && (groupsOfAudioChunks = [r], processGroupsOfAudioChunks()) }; try { if (!1 !== max_input_video_size && file.byteLength > max_input_video_size) throw new Error("exceded_max_input_video_size"); file.fileStart = 0, savedThis.logs && console.log("reader.onload"); var readingVideoInfoError = !1, readingMaxTimeTimer = setTimeout((() => { readingVideoInfoError = !0, mp4boxInputFileReadyPromise_resolver() }), video_info_read_max_time); if (mp4boxInputFile.appendBuffer(file), mp4boxInputFile.flush(), await mp4boxInputFileReadyPromise, readingVideoInfoError) throw new Error("exceded_video_info_read_max_time"); clearTimeout(readingMaxTimeTimer), savedThis.logs && console.log("reader.onload 2"), savedThis.logs && console.log("reader.onload 3"), videoTrack && (encodedFinishedPromise_resolved || await encodedFinishedPromise, videoEncoder.close()), audioTrack && (encodedAudioFinishedPromise_resolved || await encodedAudioFinishedPromise, audioEncoder.close()), void 0 !== videoResizer && videoResizer.cleanup(), savedThis.logs && console.log("reader.onload 4"); var result = await onComplete(); savedThis.onResult(result) } catch (e) { savedThis.in_onError(e) } } createMP4File() { const e = MP4Box.createFile(), t = (e.add("ftyp").set("major_brand", "mp42").set("minor_version", 0).set("compatible_brands", ["mp42", "isom"]), e.add("free"), e.add("mdat")); e.mdat = t, t.parts = [], t.write = function (e) { this.size = this.parts.map((e => e.byteLength)).reduce(((e, t) => e + t), 0), this.writeHeader(e), this.parts.forEach((t => { e.writeUint8Array(t) })) }; e.add("moov").add("mvhd").set("timescale", 1e3).set("rate", 65536).set("creation_time", 0).set("modification_time", 0).set("duration", 0).set("volume", 1).set("matrix", [65536, 0, 0, 0, 65536, 0, 0, 0, 1073741824]).set("next_track_id", 1); return e } addTrak(e, t, i) { var o = this; const a = "video" === t.type; if (!a) { e.addTrack({ id: 2, type: "audio", codec: t.codec, language: "und", timescale: this.AUDIO_TIMESCALE, channel_count: this.AUDIO_CHANNELCOUNT, samplesize: this.AUDIO_SAMPLESIZE, samplerate: this.AUDIO_SAMPLERATE, duration: void 0 }), o.audio_track = e.getTrackById(2), o.audio_track.mdia.hdlr.set("handler", "soun").set("name", ""), o.audio_track.mdia.minf.add("smhd").set("flags", 1).set("balance", 0); const i = o.audio_track.mdia.minf.add("dinf"), a = (new BoxParser["url Box"]).set("flags", 1); i.add("dref").addEntry(a); const c = (v = o.audio_track.mdia.minf.add("stbl")).add("stsd").set("version", 0).set("flags", 0), l = t.codec.split(".")[0]; if ("mp4a" === l.toLowerCase()) { var r = (new BoxParser.mp4aSampleEntry).set("data_reference_index", 1).set("channel_count", o.AUDIO_CHANNELCOUNT).set("samplesize", o.AUDIO_SAMPLESIZE).set("samplerate", o.AUDIO_SAMPLERATE); const e = new BoxParser.esdsBox; r.esds = e, r.esds.version = 0, c.addEntry(r), c.entries[0].type = t.codec } else if ("ac-3" === l || "ec-3" === l); else if ("opus" === l.toLowerCase()) { var s = (new BoxParser.OpusSampleEntry).set("data_reference_index", 1).set("channel_count", o.AUDIO_CHANNELCOUNT).set("samplesize", o.AUDIO_SAMPLESIZE).set("samplerate", o.AUDIO_SAMPLERATE), d = new BoxParser.dOpsBox, n = new MP4BoxStream(t.decoderConfig_description.buffer); d.parse(n), s.addBox(d), c.addEntry(s), c.entries[0].type = t.codec } else l.toLowerCase(); v.add("stts").set("sample_counts", []).set("sample_deltas", []), v.add("stsc").set("first_chunk", [1]).set("samples_per_chunk", [1]).set("sample_description_index", [1]), v.add("stsz").set("sample_sizes", []), v.add("stco").set("chunk_offsets", []); return e.getTrackById(2) } const c = e.moov, l = c.add("trak"); o.video_track = l; const u = c.mvhd.next_track_id; c.mvhd.next_track_id++; l.add("tkhd").set("flags", BoxParser.TKHD_FLAG_ENABLED | BoxParser.TKHD_FLAG_IN_MOVIE | BoxParser.TKHD_FLAG_IN_PREVIEW).set("creation_time", 0).set("modification_time", 0).set("track_id", u).set("duration", 0).set("layer", 0).set("alternate_group", 0).set("volume", 1).set("matrix", [65536, 0, 0, 0, 65536, 0, 0, 0, 1073741824]).set("width", (t.width || 0) << 16).set("height", (t.height || 0) << 16); const m = l.add("mdia"), _ = (m.add("mdhd").set("creation_time", 0).set("modification_time", 0).set("timescale", a ? o.VIDEO_TIMESCALE : o.AUDIO_TIMESCALE).set("duration", 0).set("language", 21956).set("languageString", "und"), m.add("hdlr").set("handler", a ? "vide" : "soun").set("name", ""), m.add("minf")); if (a) { _.add("vmhd").set("graphicsmode", 0).set("opcolor", [0, 0, 0]) } else { _.add("smhd").set("flags", 1).set("balance", 0) } const h = _.add("dinf"), p = (new BoxParser["url Box"]).set("flags", 1); h.add("dref").addEntry(p); var v = _.add("stbl"); if (a) { var g; if ("avc1" == i) { (g = new BoxParser.avc1SampleEntry).data_reference_index = 1, g.set("width", t.width || 0).set("height", t.height || 0).set("horizresolution", 72 << 16).set("vertresolution", 72 << 16).set("frame_count", 1).set("compressorname", "").set("depth", 24); var f = new BoxParser.avcCBox; n = new MP4BoxStream(t.avcDecoderConfigRecord); f.parse(n), g.addBox(f) } else if ("hvc1" == i) { if ((g = new BoxParser.hvc1SampleEntry).data_reference_index = 1, g.set("width", t.width || 0).set("height", t.height || 0).set("horizresolution", 72 << 16).set("vertresolution", 72 << 16).set("frame_count", 1).set("compressorname", "").set("depth", 24), t.hdrMetadata) { const e = new BoxParser.colrBox; if (e.colour_type = "nclx", e.colour_primaries = t.hdrMetadata.colorPrimaries || 9, e.transfer_characteristics = t.hdrMetadata.transferCharacteristics || 16, e.matrix_coefficients = t.hdrMetadata.matrixCoefficients || 9, e.full_range_flag = t.hdrMetadata.fullRange || !0, g.addBox(e), t.hdrMetadata.masteringDisplayData) { const e = new BoxParser.mdcvBox; e.display_primaries = t.hdrMetadata.masteringDisplayData.primaries, e.white_point = t.hdrMetadata.masteringDisplayData.whitePoint, e.max_display_mastering_luminance = t.hdrMetadata.masteringDisplayData.maxLuminance, e.min_display_mastering_luminance = t.hdrMetadata.masteringDisplayData.minLuminance, g.addBox(e) } if (t.hdrMetadata.contentLightLevel) { const e = new BoxParser.clliBox; e.max_content_light_level = t.hdrMetadata.contentLightLevel.maxCLL, e.max_pic_average_light_level = t.hdrMetadata.contentLightLevel.maxFALL, g.addBox(e) } } var x = new BoxParser.hvcCBox; o.logs && console.log("config.hvcDecoderConfigRecord", t.hvcDecoderConfigRecord); n = new MP4BoxStream(t.hvcDecoderConfigRecord); x.parse(n), t.hevcParams && (x.general_profile_space = t.hevcParams.profileSpace || 0, x.general_tier_flag = t.hevcParams.tierFlag || 0, x.general_profile_idc = t.hevcParams.profileIdc || 1, x.general_profile_compatibility = t.hevcParams.profileCompatibility || 0, x.general_level_idc = t.hevcParams.levelIdc || 120), g.addBox(x) } v.add("stsd").addEntry(g) } v.add("stts").set("sample_counts", []).set("sample_deltas", []); if (a) { v.add("stss").set("sample_numbers", []) } v.add("stsc").set("first_chunk", [1]).set("samples_per_chunk", [1]).set("sample_description_index", [1]), v.add("stsz").set("sample_sizes", []), v.add("stco").set("chunk_offsets", []); return l } addSample(e, t, i, o, a, r, s = null, d = null) { var n = this; const c = "vide" === t.mdia.hdlr.handler; try { "hvc1" === t.mdia.minf.stbl.stsd.entries[0].type } catch (e) { } if (n.isFirstVideoSample && c) { n.isFirstVideoSample = !1; const e = 4 + i[0] << 24 + i[1] << 16 + i[2] << 8 + i[3]; i = i.slice(e) } e.mdat.parts.push(i); const l = a / (c ? n.VIDEO_TIMESCALE : n.AUDIO_TIMESCALE) * 1e3; t.samples_duration += l, t.tkhd.duration += l, t.mdia.mdhd.duration += a, r && (e.moov.mvhd.duration += l); const u = t.mdia.minf.stbl; let m = u.stts.sample_deltas.length - 1; u.stts.sample_deltas[m] !== a ? (u.stts.sample_deltas.push(a), u.stts.sample_counts.push(1)) : u.stts.sample_counts[m]++, c && o && u.stss.sample_numbers.push(u.stts.sample_counts.reduce(((e, t) => e + t))), u.stco.chunk_offsets.push(n.chunkOffset), n.chunkOffset += i.byteLength, u.stsz.sample_sizes.push(i.byteLength), u.stsz.sample_count++ } findClosestIndex(e, t) { let i = -1, o = 1 / 0; return e.forEach(((e, a) => { const r = Math.abs(e - t); r < o && (o = r, i = a) })), i } getDimensionsForResize(e, t, i, o = !1, a = !1) { if (e <= i && t <= i) { if (o) return !1; { let i = e, o = t; return a && (i = e % 2 == 0 ? e : e - 1, o = t % 2 == 0 ? t : t - 1), { width: i, height: o } } } let r = Math.min(i / e, i / t), s = Math.round(e * r), d = Math.round(t * r); return a && (s = s % 2 == 0 ? s : s - 1, d = d % 2 == 0 ? d : d - 1), { width: s, height: d } } async getSupportedAudioBitrates(e, t = !1) { if (!e) return []; const i = [32e3, 64e3, 96e3, 128e3, 16e4, 192e3, 256e3, 32e4], o = []; !1 === t && (t = e.codec); for (const a of i) { const i = { codec: t, numberOfChannels: e.audio.channel_count, sampleRate: e.audio.sample_rate, bitrate: a, bitratemode: "variable" }; try { const e = await AudioEncoder.isConfigSupported(i); e.supported && o.push(e.config.bitrate) } catch (e) { } } return o } getAVCCodec(e, t, i) { const o = i / 1e6, a = e * t; let r, s; return a <= 345600 ? o <= 2 ? (r = "baseline", s = "3.1") : o <= 4 ? (r = "main", s = "3.1") : (r = "high", s = "3.1") : a <= 921600 ? o <= 4 ? (r = "main", s = "4.0") : o <= 8 ? (r = "high", s = "4.0") : (r = "high10", s = "4.1") : a <= 2073600 ? o <= 8 ? (r = "high", s = "4.1") : o <= 12 ? (r = "high10", s = "4.1") : (r = "high422", s = "5.0") : o <= 15 ? (r = "high10", s = "5.1") : o <= 20 ? (r = "high422", s = "5.1") : (r = "high444", s = "5.2"), `avc1.${{ baseline: "42", main: "4D", high: "64", high10: "64", high422: "64", high444: "64" }[r]}00${{ 3.1: "1F", "4.0": "28", 4.1: "29", "5.0": "32", 5.1: "33", 5.2: "34" }[s]}` } async helper_preprocess_video_info_function(e) { return {} } getHVC1Codec(e, t, i) { const o = i / 1e6, a = e * t; let r; r = a <= 518400 ? o <= 3 ? "L30" : "L60" : a <= 2073600 ? o <= 10 ? "L63" : o <= 20 ? "L90" : "L93" : a <= 8847360 ? o <= 30 ? "L120" : "L123" : o <= 60 ? "L150" : o <= 80 ? "L153" : "L156"; return `hvc1.1.6.${r}.B0` } }