#299 Hopefully fix the playback issues introduced when adding music library-support
This commit is contained in:
parent
27b5184852
commit
ad6dcb4a33
@ -35,6 +35,7 @@ class PlexTranscoder {
|
||||
this.updateInterval = 30000
|
||||
this.updatingPlex = undefined
|
||||
this.playState = "stopped"
|
||||
this.mediaHasNoVideo = false;
|
||||
this.albumArt = {
|
||||
attempted : false,
|
||||
path: null,
|
||||
@ -48,23 +49,26 @@ class PlexTranscoder {
|
||||
this.log(` deinterlace: ${deinterlace}`)
|
||||
this.log(` streamPath: ${this.settings.streamPath}`)
|
||||
|
||||
this.setTranscodingArgs(stream.directPlay, true, false, false);
|
||||
await this.tryToDetectAudioOnly();
|
||||
|
||||
if (this.settings.streamPath === 'direct' || this.settings.forceDirectPlay) {
|
||||
if (this.settings.enableSubtitles) {
|
||||
console.log("Direct play is forced, so subtitles are forcibly disabled.");
|
||||
this.log("Direct play is forced, so subtitles are forcibly disabled.");
|
||||
this.settings.enableSubtitles = false;
|
||||
}
|
||||
stream = {directPlay: true}
|
||||
} else {
|
||||
try {
|
||||
this.log("Setting transcoding parameters")
|
||||
this.setTranscodingArgs(stream.directPlay, true, deinterlace, true)
|
||||
this.setTranscodingArgs(stream.directPlay, true, deinterlace, this.mediaHasNoVideo)
|
||||
await this.getDecision(stream.directPlay);
|
||||
if (this.isDirectPlay()) {
|
||||
stream.directPlay = true;
|
||||
stream.streamUrl = this.plexFile;
|
||||
}
|
||||
} catch (err) {
|
||||
this.log("Error when getting decision. 1. Check Plex connection. 2. This might also be a sign that plex direct play and transcode settings are too strict and it can't find any allowed action for the selected video.")
|
||||
console.error("Error when getting decision. 1. Check Plex connection. 2. This might also be a sign that plex direct play and transcode settings are too strict and it can't find any allowed action for the selected video.", err)
|
||||
stream.directPlay = true;
|
||||
}
|
||||
}
|
||||
@ -74,7 +78,7 @@ class PlexTranscoder {
|
||||
}
|
||||
this.log("Direct play forced or native paths enabled")
|
||||
stream.directPlay = true
|
||||
this.setTranscodingArgs(stream.directPlay, true, false)
|
||||
this.setTranscodingArgs(stream.directPlay, true, false, this.mediaHasNoVideo )
|
||||
// Update transcode decision for session
|
||||
await this.getDecision(stream.directPlay);
|
||||
stream.streamUrl = (this.settings.streamPath === 'direct') ? this.file : this.plexFile;
|
||||
@ -92,7 +96,7 @@ class PlexTranscoder {
|
||||
} else if (this.isVideoDirectStream() === false) {
|
||||
this.log("Decision: Should transcode")
|
||||
// Change transcoding arguments to be the user chosen transcode parameters
|
||||
this.setTranscodingArgs(stream.directPlay, false, deinterlace)
|
||||
this.setTranscodingArgs(stream.directPlay, false, deinterlace, this.mediaHasNoVideo)
|
||||
// Update transcode decision for session
|
||||
await this.getDecision(stream.directPlay);
|
||||
stream.streamUrl = `${this.transcodeUrlBase}${this.transcodingArgs}`
|
||||
@ -114,13 +118,13 @@ class PlexTranscoder {
|
||||
return stream
|
||||
}
|
||||
|
||||
setTranscodingArgs(directPlay, directStream, deinterlace, firstTry) {
|
||||
setTranscodingArgs(directPlay, directStream, deinterlace, audioOnly) {
|
||||
let resolution = (directStream) ? this.settings.maxPlayableResolution : this.settings.maxTranscodeResolution
|
||||
let bitrate = (directStream) ? this.settings.directStreamBitrate : this.settings.transcodeBitrate
|
||||
let mediaBufferSize = (directStream) ? this.settings.mediaBufferSize : this.settings.transcodeMediaBufferSize
|
||||
let subtitles = (this.settings.enableSubtitles) ? "burn" : "none" // subtitle options: burn, none, embedded, sidecar
|
||||
let streamContainer = "mpegts" // Other option is mkv, mkv has the option of copying it's subs for later processing
|
||||
let isDirectPlay = (directPlay) ? '1' : (firstTry? '': '0');
|
||||
let isDirectPlay = (directPlay) ? '1' : '0';
|
||||
let hasMDE = '1';
|
||||
|
||||
let videoQuality=`100` // Not sure how this applies, maybe this works if maxVideoBitrate is not set
|
||||
@ -137,12 +141,17 @@ class PlexTranscoder {
|
||||
vc = "av1";
|
||||
}
|
||||
|
||||
let clientProfile=`add-transcode-target(type=videoProfile&protocol=${this.settings.streamProtocol}&container=${streamContainer}&videoCodec=${vc}&audioCodec=${this.settings.audioCodecs}&subtitleCodec=&context=streaming&replace=true)+\
|
||||
let clientProfile ="";
|
||||
if (! audioOnly ) {
|
||||
clientProfile=`add-transcode-target(type=videoProfile&protocol=${this.settings.streamProtocol}&container=${streamContainer}&videoCodec=${vc}&audioCodec=${this.settings.audioCodecs}&subtitleCodec=&context=streaming&replace=true)+\
|
||||
add-transcode-target-settings(type=videoProfile&context=streaming&protocol=${this.settings.streamProtocol}&CopyMatroskaAttachments=true)+\
|
||||
add-transcode-target-settings(type=videoProfile&context=streaming&protocol=${this.settings.streamProtocol}&BreakNonKeyframes=true)+\
|
||||
add-limitation(scope=videoCodec&scopeName=*&type=upperBound&name=video.width&value=${resolutionArr[0]})+\
|
||||
add-limitation(scope=videoCodec&scopeName=*&type=upperBound&name=video.height&value=${resolutionArr[1]})`
|
||||
|
||||
} else {
|
||||
clientProfile=`add-transcode-target(type=musicProfile&protocol=${this.settings.streamProtocol}&container=${streamContainer}&audioCodec=${this.settings.audioCodecs}&subtitleCodec=&context=streaming&replace=true)`
|
||||
|
||||
}
|
||||
// Set transcode settings per audio codec
|
||||
this.settings.audioCodecs.split(",").forEach(function (codec) {
|
||||
clientProfile+=`+add-transcode-target-audio-codec(type=videoProfile&context=streaming&protocol=${this.settings.streamProtocol}&audioCodec=${codec})`
|
||||
@ -196,7 +205,7 @@ lang=en`
|
||||
try {
|
||||
return this.getVideoStats().videoDecision === "copy";
|
||||
} catch (e) {
|
||||
console.log("Error at decision:", e);
|
||||
console.error("Error at decision:", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -216,7 +225,7 @@ lang=en`
|
||||
}
|
||||
return this.getVideoStats().videoDecision === "copy" && this.getVideoStats().audioDecision === "copy";
|
||||
} catch (e) {
|
||||
console.log("Error at decision:" , e);
|
||||
console.error("Error at decision:" , e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -262,7 +271,7 @@ lang=en`
|
||||
}
|
||||
}.bind(this) )
|
||||
} catch (e) {
|
||||
console.log("Error at decision:" , e);
|
||||
console.error("Error at decision:" , e);
|
||||
}
|
||||
if (typeof(ret.videoCodec) === 'undefined') {
|
||||
ret.audioOnly = true;
|
||||
@ -297,11 +306,11 @@ lang=en`
|
||||
}
|
||||
})
|
||||
} catch (e) {
|
||||
console.log("Error at get media info:" + e);
|
||||
console.error("Error at get media info:" + e);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
console.error("Error getting audio index",err);
|
||||
});
|
||||
|
||||
this.log(`Found audio index: ${index}`)
|
||||
@ -326,36 +335,42 @@ lang=en`
|
||||
|
||||
// Print error message if transcode not possible
|
||||
// TODO: handle failure better
|
||||
if (res.data.MediaContainer.mdeDecisionCode === 1000) {
|
||||
this.log("mde decision code 1000, so it's all right?");
|
||||
return;
|
||||
}
|
||||
|
||||
let transcodeDecisionCode = res.data.MediaContainer.transcodeDecisionCode;
|
||||
if (
|
||||
( typeof(transcodeDecisionCode) === 'undefined' )
|
||||
) {
|
||||
this.decisionJson.MediaContainer.transcodeDecisionCode = 'novideo';
|
||||
console.log("Audio-only file detected");
|
||||
await this.tryToGetAlbumArt();
|
||||
this.log("Strange case, attempt direct play");
|
||||
} else if (!(directPlay || transcodeDecisionCode == "1001")) {
|
||||
console.log(`IMPORTANT: Recieved transcode decision code ${transcodeDecisionCode}! Expected code 1001.`)
|
||||
console.log(`Error message: '${res.data.MediaContainer.transcodeDecisionText}'`)
|
||||
this.log(`IMPORTANT: Recieved transcode decision code ${transcodeDecisionCode}! Expected code 1001.`)
|
||||
this.log(`Error message: '${res.data.MediaContainer.transcodeDecisionText}'`)
|
||||
}
|
||||
}
|
||||
|
||||
async tryToGetAlbumArt() {
|
||||
|
||||
async tryToDetectAudioOnly() {
|
||||
try {
|
||||
if(this.albumArt.attempted ) {
|
||||
return;
|
||||
}
|
||||
this.albumArt.attempted = true;
|
||||
|
||||
this.log("Try to get album art:");
|
||||
this.log("Try to detect audio only:");
|
||||
let url = `${this.server.uri}${this.key}?${this.transcodingArgs}`;
|
||||
let res = await axios.get(url, {
|
||||
headers: { Accept: 'application/json' }
|
||||
});
|
||||
|
||||
let mediaContainer = res.data.MediaContainer;
|
||||
if (typeof(mediaContainer) !== 'undefined') {
|
||||
for( let i = 0; i < mediaContainer.Metadata.length; i++) {
|
||||
console.log("got art: " + mediaContainer.Metadata[i].thumb );
|
||||
this.albumArt.path = `${this.server.uri}${mediaContainer.Metadata[i].thumb}?X-Plex-Token=${this.server.accessToken}`;
|
||||
let metadata = getOneOrUndefined( mediaContainer, "Metadata");
|
||||
if (typeof(metadata) !== 'undefined') {
|
||||
this.albumArt.path = `${this.server.uri}${metadata.thumb}?X-Plex-Token=${this.server.accessToken}`;
|
||||
|
||||
let media = getOneOrUndefined( metadata, "Media");
|
||||
if (typeof(media) !== 'undefined') {
|
||||
if (typeof(media.videoCodec)==='undefined') {
|
||||
this.log("Audio-only file detected");
|
||||
this.mediaHasNoVideo = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
@ -447,4 +462,19 @@ function parsePixelAspectRatio(s) {
|
||||
q: parseInt(x[1], 10),
|
||||
}
|
||||
}
|
||||
|
||||
function getOneOrUndefined(object, field) {
|
||||
if (typeof(object) === 'undefined') {
|
||||
return undefined;
|
||||
}
|
||||
if ( typeof(object[field]) === "undefined") {
|
||||
return undefined;
|
||||
}
|
||||
let x = object[field];
|
||||
if (x.length < 1) {
|
||||
return undefined;
|
||||
}
|
||||
return x[0];
|
||||
}
|
||||
|
||||
module.exports = PlexTranscoder
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user