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…
	
	Add table
		Add a link
		
	
		Reference in a new issue