mirror of
https://github.com/TeamPiped/Piped.git
synced 2024-08-14 23:57:27 +00:00
Simplify export and filter manifests from dash generation.
This commit is contained in:
parent
bf0fb000e3
commit
acff16a8d4
2 changed files with 183 additions and 179 deletions
|
@ -283,9 +283,10 @@ export default {
|
||||||
mime = "application/x-mpegURL";
|
mime = "application/x-mpegURL";
|
||||||
} else if (this.video.audioStreams.length > 0 && !lbry && MseSupport) {
|
} else if (this.video.audioStreams.length > 0 && !lbry && MseSupport) {
|
||||||
if (!this.video.dash) {
|
if (!this.video.dash) {
|
||||||
const dash = (
|
const dash = (await import("../utils/DashUtils.js")).generate_dash_file_from_formats(
|
||||||
await import("@/utils/DashUtils.js").then(mod => mod.default)
|
streams,
|
||||||
).generate_dash_file_from_formats(streams, this.video.duration);
|
this.video.duration,
|
||||||
|
);
|
||||||
|
|
||||||
uri = "data:application/dash+xml;charset=utf-8;base64," + btoa(dash);
|
uri = "data:application/dash+xml;charset=utf-8;base64," + btoa(dash);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -4,201 +4,204 @@ import { Buffer } from "buffer";
|
||||||
window.Buffer = Buffer;
|
window.Buffer = Buffer;
|
||||||
import { json2xml } from "xml-js";
|
import { json2xml } from "xml-js";
|
||||||
|
|
||||||
const DashUtils = {
|
export function generate_dash_file_from_formats(VideoFormats, VideoLength) {
|
||||||
generate_dash_file_from_formats(VideoFormats, VideoLength) {
|
const generatedJSON = generate_xmljs_json_from_data(VideoFormats, VideoLength);
|
||||||
const generatedJSON = this.generate_xmljs_json_from_data(VideoFormats, VideoLength);
|
return json2xml(generatedJSON);
|
||||||
return json2xml(generatedJSON);
|
}
|
||||||
},
|
|
||||||
generate_xmljs_json_from_data(VideoFormatArray, VideoLength) {
|
function generate_xmljs_json_from_data(VideoFormatArray, VideoLength) {
|
||||||
const convertJSON = {
|
const convertJSON = {
|
||||||
declaration: {
|
declaration: {
|
||||||
attributes: {
|
attributes: {
|
||||||
version: "1.0",
|
version: "1.0",
|
||||||
encoding: "utf-8",
|
encoding: "utf-8",
|
||||||
},
|
|
||||||
},
|
},
|
||||||
elements: [
|
},
|
||||||
{
|
elements: [
|
||||||
type: "element",
|
{
|
||||||
name: "MPD",
|
type: "element",
|
||||||
attributes: {
|
name: "MPD",
|
||||||
xmlns: "urn:mpeg:dash:schema:mpd:2011",
|
attributes: {
|
||||||
profiles: "urn:mpeg:dash:profile:full:2011",
|
xmlns: "urn:mpeg:dash:schema:mpd:2011",
|
||||||
minBufferTime: "PT1.5S",
|
profiles: "urn:mpeg:dash:profile:full:2011",
|
||||||
type: "static",
|
minBufferTime: "PT1.5S",
|
||||||
mediaPresentationDuration: `PT${VideoLength}S`,
|
type: "static",
|
||||||
},
|
mediaPresentationDuration: `PT${VideoLength}S`,
|
||||||
elements: [
|
|
||||||
{
|
|
||||||
type: "element",
|
|
||||||
name: "Period",
|
|
||||||
elements: this.generate_adaptation_set(VideoFormatArray),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
],
|
elements: [
|
||||||
};
|
{
|
||||||
return convertJSON;
|
type: "element",
|
||||||
},
|
name: "Period",
|
||||||
generate_adaptation_set(VideoFormatArray) {
|
elements: generate_adaptation_set(VideoFormatArray),
|
||||||
const adaptationSets = [];
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
return convertJSON;
|
||||||
|
}
|
||||||
|
|
||||||
let mimeAudioObjs = [];
|
function generate_adaptation_set(VideoFormatArray) {
|
||||||
|
const adaptationSets = [];
|
||||||
|
|
||||||
VideoFormatArray.forEach(videoFormat => {
|
let mimeAudioObjs = [];
|
||||||
// the dual formats should not be used
|
|
||||||
if (videoFormat.mimeType.indexOf("video") != -1 && !videoFormat.videoOnly) {
|
VideoFormatArray.forEach(videoFormat => {
|
||||||
|
// the dual formats should not be used
|
||||||
|
if (
|
||||||
|
(videoFormat.mimeType.includes("video") && !videoFormat.videoOnly) ||
|
||||||
|
videoFormat.mimeType.includes("application")
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const audioTrackId = videoFormat.audioTrackId;
|
||||||
|
const mimeType = videoFormat.mimeType;
|
||||||
|
|
||||||
|
for (let i = 0; i < mimeAudioObjs.length; i++) {
|
||||||
|
const mimeAudioObj = mimeAudioObjs[i];
|
||||||
|
|
||||||
|
if (mimeAudioObj.audioTrackId == audioTrackId && mimeAudioObj.mimeType == mimeType) {
|
||||||
|
mimeAudioObj.videoFormats.push(videoFormat);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const audioTrackId = videoFormat.audioTrackId;
|
mimeAudioObjs.push({
|
||||||
const mimeType = videoFormat.mimeType;
|
audioTrackId,
|
||||||
|
mimeType,
|
||||||
for (let i = 0; i < mimeAudioObjs.length; i++) {
|
videoFormats: [videoFormat],
|
||||||
const mimeAudioObj = mimeAudioObjs[i];
|
|
||||||
|
|
||||||
if (mimeAudioObj.audioTrackId == audioTrackId && mimeAudioObj.mimeType == mimeType) {
|
|
||||||
mimeAudioObj.videoFormats.push(videoFormat);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mimeAudioObjs.push({
|
|
||||||
audioTrackId,
|
|
||||||
mimeType,
|
|
||||||
videoFormats: [videoFormat],
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
mimeAudioObjs.forEach(mimeAudioObj => {
|
mimeAudioObjs.forEach(mimeAudioObj => {
|
||||||
const adapSet = {
|
const adapSet = {
|
||||||
type: "element",
|
type: "element",
|
||||||
name: "AdaptationSet",
|
name: "AdaptationSet",
|
||||||
attributes: {
|
attributes: {
|
||||||
id: mimeAudioObj.audioTrackId,
|
id: mimeAudioObj.audioTrackId,
|
||||||
lang: mimeAudioObj.audioTrackId?.substr(0, 2),
|
lang: mimeAudioObj.audioTrackId?.substr(0, 2),
|
||||||
mimeType: mimeAudioObj.mimeType,
|
mimeType: mimeAudioObj.mimeType,
|
||||||
startWithSAP: "1",
|
startWithSAP: "1",
|
||||||
subsegmentAlignment: "true",
|
subsegmentAlignment: "true",
|
||||||
},
|
},
|
||||||
elements: [],
|
elements: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
let isVideoFormat = false;
|
let isVideoFormat = false;
|
||||||
|
|
||||||
if (mimeAudioObj.mimeType.includes("video")) {
|
if (mimeAudioObj.mimeType.includes("video")) {
|
||||||
isVideoFormat = true;
|
isVideoFormat = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isVideoFormat) {
|
||||||
|
adapSet.attributes.scanType = "progressive";
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < mimeAudioObj.videoFormats.length; i++) {
|
||||||
|
const videoFormat = mimeAudioObj.videoFormats[i];
|
||||||
if (isVideoFormat) {
|
if (isVideoFormat) {
|
||||||
adapSet.attributes.scanType = "progressive";
|
adapSet.elements.push(generate_representation_video(videoFormat));
|
||||||
|
} else {
|
||||||
|
adapSet.elements.push(generate_representation_audio(videoFormat));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (var i = 0; i < mimeAudioObj.videoFormats.length; i++) {
|
adaptationSets.push(adapSet);
|
||||||
const videoFormat = mimeAudioObj.videoFormats[i];
|
});
|
||||||
if (isVideoFormat) {
|
return adaptationSets;
|
||||||
adapSet.elements.push(this.generate_representation_video(videoFormat));
|
}
|
||||||
} else {
|
|
||||||
adapSet.elements.push(this.generate_representation_audio(videoFormat));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
adaptationSets.push(adapSet);
|
function generate_representation_audio(Format) {
|
||||||
});
|
const representation = {
|
||||||
return adaptationSets;
|
type: "element",
|
||||||
},
|
name: "Representation",
|
||||||
generate_representation_audio(Format) {
|
attributes: {
|
||||||
const representation = {
|
id: Format.itag,
|
||||||
type: "element",
|
codecs: Format.codec,
|
||||||
name: "Representation",
|
bandwidth: Format.bitrate,
|
||||||
attributes: {
|
},
|
||||||
id: Format.itag,
|
elements: [
|
||||||
codecs: Format.codec,
|
{
|
||||||
bandwidth: Format.bitrate,
|
type: "element",
|
||||||
|
name: "AudioChannelConfiguration",
|
||||||
|
attributes: {
|
||||||
|
schemeIdUri: "urn:mpeg:dash:23003:3:audio_channel_configuration:2011",
|
||||||
|
value: "2",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
elements: [
|
{
|
||||||
{
|
type: "element",
|
||||||
type: "element",
|
name: "BaseURL",
|
||||||
name: "AudioChannelConfiguration",
|
elements: [
|
||||||
attributes: {
|
{
|
||||||
schemeIdUri: "urn:mpeg:dash:23003:3:audio_channel_configuration:2011",
|
type: "text",
|
||||||
value: "2",
|
text: Format.url,
|
||||||
},
|
},
|
||||||
},
|
],
|
||||||
{
|
|
||||||
type: "element",
|
|
||||||
name: "BaseURL",
|
|
||||||
elements: [
|
|
||||||
{
|
|
||||||
type: "text",
|
|
||||||
text: Format.url,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: "element",
|
|
||||||
name: "SegmentBase",
|
|
||||||
attributes: {
|
|
||||||
indexRange: `${Format.indexStart}-${Format.indexEnd}`,
|
|
||||||
},
|
|
||||||
elements: [
|
|
||||||
{
|
|
||||||
type: "element",
|
|
||||||
name: "Initialization",
|
|
||||||
attributes: {
|
|
||||||
range: `${Format.initStart}-${Format.initEnd}`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
return representation;
|
|
||||||
},
|
|
||||||
generate_representation_video(Format) {
|
|
||||||
const representation = {
|
|
||||||
type: "element",
|
|
||||||
name: "Representation",
|
|
||||||
attributes: {
|
|
||||||
id: Format.itag,
|
|
||||||
codecs: Format.codec,
|
|
||||||
bandwidth: Format.bitrate,
|
|
||||||
width: Format.width,
|
|
||||||
height: Format.height,
|
|
||||||
maxPlayoutRate: "1",
|
|
||||||
frameRate: Format.fps,
|
|
||||||
},
|
},
|
||||||
elements: [
|
{
|
||||||
{
|
type: "element",
|
||||||
type: "element",
|
name: "SegmentBase",
|
||||||
name: "BaseURL",
|
attributes: {
|
||||||
elements: [
|
indexRange: `${Format.indexStart}-${Format.indexEnd}`,
|
||||||
{
|
|
||||||
type: "text",
|
|
||||||
text: Format.url,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
{
|
elements: [
|
||||||
type: "element",
|
{
|
||||||
name: "SegmentBase",
|
type: "element",
|
||||||
attributes: {
|
name: "Initialization",
|
||||||
indexRange: `${Format.indexStart}-${Format.indexEnd}`,
|
attributes: {
|
||||||
|
range: `${Format.initStart}-${Format.initEnd}`,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
elements: [
|
],
|
||||||
{
|
},
|
||||||
type: "element",
|
],
|
||||||
name: "Initialization",
|
};
|
||||||
attributes: {
|
return representation;
|
||||||
range: `${Format.initStart}-${Format.initEnd}`,
|
}
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
return representation;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export default DashUtils;
|
function generate_representation_video(Format) {
|
||||||
|
const representation = {
|
||||||
|
type: "element",
|
||||||
|
name: "Representation",
|
||||||
|
attributes: {
|
||||||
|
id: Format.itag,
|
||||||
|
codecs: Format.codec,
|
||||||
|
bandwidth: Format.bitrate,
|
||||||
|
width: Format.width,
|
||||||
|
height: Format.height,
|
||||||
|
maxPlayoutRate: "1",
|
||||||
|
frameRate: Format.fps,
|
||||||
|
},
|
||||||
|
elements: [
|
||||||
|
{
|
||||||
|
type: "element",
|
||||||
|
name: "BaseURL",
|
||||||
|
elements: [
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
text: Format.url,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "element",
|
||||||
|
name: "SegmentBase",
|
||||||
|
attributes: {
|
||||||
|
indexRange: `${Format.indexStart}-${Format.indexEnd}`,
|
||||||
|
},
|
||||||
|
elements: [
|
||||||
|
{
|
||||||
|
type: "element",
|
||||||
|
name: "Initialization",
|
||||||
|
attributes: {
|
||||||
|
range: `${Format.initStart}-${Format.initEnd}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
return representation;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue