Merge branch 'dev/1.0.x' into dev/1.1.x
This commit is contained in:
commit
7a4c3bd709
@ -3,7 +3,7 @@
|
||||
|
||||
Create live TV channel streams from media on your Plex servers.
|
||||
|
||||
dizqueTV is a fork of the project previously-known as [pseudotv-plex](https://gitlab.com/DEFENDORe/pseudotv-plex) or [pseudotv](https://github.com/DEFENDORe/pseudotv). New repository because of lack of activity from the main repository and the name change is because projects with the old name already existed and were created long before this approach and it was causing confusion. You can migrate from pseudoTV 0.0.51 to dizqueTV by renaming the .pseudotv folder to .dizquetv and running the new executable (or doing a similar trick with the volumes used by the docker containers).
|
||||
**dizqueTV** ( *dis·keˈtiːˈvi* ) is a fork of the project previously-known as [pseudotv-plex](https://gitlab.com/DEFENDORe/pseudotv-plex) or [pseudotv](https://github.com/DEFENDORe/pseudotv). New repository because of lack of activity from the main repository and the name change is because projects with the old name already existed and were created long before this approach and it was causing confusion. You can migrate from pseudoTV 0.0.51 to dizqueTV by renaming the .pseudotv folder to .dizquetv and running the new executable (or doing a similar trick with the volumes used by the docker containers).
|
||||
|
||||
<img src="./resources/dizquetv.png" width="200">
|
||||
|
||||
|
||||
@ -349,8 +349,8 @@ function api(db, channelDB, fillerDB, xmltvInterval, guideService ) {
|
||||
db['plex-settings'].update({ _id: req.body._id }, {
|
||||
streamPath: 'plex',
|
||||
debugLogging: true,
|
||||
directStreamBitrate: '40000',
|
||||
transcodeBitrate: '3000',
|
||||
directStreamBitrate: '20000',
|
||||
transcodeBitrate: '2000',
|
||||
mediaBufferSize: 1000,
|
||||
transcodeMediaBufferSize: 20000,
|
||||
maxPlayableResolution: "1920x1080",
|
||||
@ -534,7 +534,8 @@ function api(db, channelDB, fillerDB, xmltvInterval, guideService ) {
|
||||
res.type('text')
|
||||
let channels = await channelDB.getAllChannels();
|
||||
channels.sort((a, b) => { return a.number < b.number ? -1 : 1 })
|
||||
var data = "#EXTM3U\n"
|
||||
let tvg = `${req.protocol}://${req.get('host')}/api/xmltv.xml`
|
||||
var data = `#EXTM3U url-tvg="${tvg}" x-tvg-url="${tvg}"\n`;
|
||||
for (var i = 0; i < channels.length; i++) {
|
||||
if (channels[i].stealth!==true) {
|
||||
data += `#EXTINF:0 tvg-id="${channels[i].number}" tvg-chno="${channels[i].number}" tvg-name="${channels[i].name}" tvg-logo="${channels[i].icon}" group-title="dizqueTV",${channels[i].name}\n`
|
||||
|
||||
@ -79,8 +79,8 @@ function basicDB(db) {
|
||||
db['plex-settings'].save({
|
||||
streamPath: 'plex',
|
||||
debugLogging: true,
|
||||
directStreamBitrate: '40000',
|
||||
transcodeBitrate: '3000',
|
||||
directStreamBitrate: '20000',
|
||||
transcodeBitrate: '2000',
|
||||
mediaBufferSize: 1000,
|
||||
transcodeMediaBufferSize: 20000,
|
||||
maxPlayableResolution: "1920x1080",
|
||||
@ -380,7 +380,7 @@ function ffmpeg() {
|
||||
videoEncoder: "mpeg2video",
|
||||
audioEncoder: "ac3",
|
||||
targetResolution: "1920x1080",
|
||||
videoBitrate: 10000,
|
||||
videoBitrate: 2000,
|
||||
videoBufSize: 2000,
|
||||
audioBitrate: 192,
|
||||
audioBufSize: 50,
|
||||
|
||||
@ -16,6 +16,7 @@ class PlexTranscoder {
|
||||
this.log("Debug logging enabled")
|
||||
|
||||
this.key = lineupItem.key
|
||||
this.metadataPath = `${server.uri}${lineupItem.key}?X-Plex-Token=${server.accessToken}`
|
||||
this.plexFile = `${server.uri}${lineupItem.plexFile}?X-Plex-Token=${server.accessToken}`
|
||||
if (typeof(lineupItem.file)!=='undefined') {
|
||||
this.file = lineupItem.file.replace(settings.pathReplace, settings.pathReplaceWith)
|
||||
@ -87,6 +88,8 @@ class PlexTranscoder {
|
||||
this.log("Decision: Direct stream. Audio is being transcoded")
|
||||
stream.separateVideoStream = (this.settings.streamPath === 'direct') ? this.file : this.plexFile;
|
||||
stream.streamUrl = `${this.transcodeUrlBase}${this.transcodingArgs}`
|
||||
this.directInfo = await this.getDirectInfo();
|
||||
this.videoIsDirect = true;
|
||||
}
|
||||
stream.streamStats = this.getVideoStats();
|
||||
|
||||
@ -207,10 +210,14 @@ lang=en`
|
||||
let streams = this.decisionJson.MediaContainer.Metadata[0].Media[0].Part[0].Stream
|
||||
|
||||
ret.duration = parseFloat( this.decisionJson.MediaContainer.Metadata[0].Media[0].Part[0].duration );
|
||||
streams.forEach(function (stream) {
|
||||
streams.forEach(function (_stream, $index) {
|
||||
// Video
|
||||
let stream = _stream;
|
||||
if (stream["streamType"] == "1") {
|
||||
ret.anamorphic = (stream.anamorphic === "1");
|
||||
if ( this.videoIsDirect === true && typeof(this.directInfo) !== 'undefined') {
|
||||
stream = this.directInfo.MediaContainer.Metadata[0].Media[0].Part[0].Stream[$index];
|
||||
}
|
||||
ret.anamorphic = ( (stream.anamorphic === "1") || (stream.anamorphic === true) );
|
||||
if (ret.anamorphic) {
|
||||
let parsed = parsePixelAspectRatio(stream.pixelAspectRatio);
|
||||
if (isNaN(parsed.p) || isNaN(parsed.q) ) {
|
||||
@ -236,7 +243,7 @@ lang=en`
|
||||
ret.audioCodec = stream["codec"];
|
||||
ret.audioDecision = (typeof stream.decision === 'undefined') ? 'copy' : stream.decision;
|
||||
}
|
||||
})
|
||||
}.bind(this) )
|
||||
} catch (e) {
|
||||
console.log("Error at decision:" + e);
|
||||
}
|
||||
@ -277,11 +284,15 @@ lang=en`
|
||||
return index
|
||||
}
|
||||
|
||||
async getDirectInfo() {
|
||||
return (await axios.get(this.metadataPath) ).data;
|
||||
|
||||
}
|
||||
|
||||
async getDecision(directPlay) {
|
||||
await axios.get(`${this.server.uri}/video/:/transcode/universal/decision?${this.transcodingArgs}`, {
|
||||
let res = await axios.get(`${this.server.uri}/video/:/transcode/universal/decision?${this.transcodingArgs}`, {
|
||||
headers: { Accept: 'application/json' }
|
||||
})
|
||||
.then((res) => {
|
||||
this.decisionJson = res.data;
|
||||
|
||||
this.log("Recieved transcode decision:")
|
||||
@ -294,7 +305,6 @@ lang=en`
|
||||
console.log(`IMPORTANT: Recieved transcode decision code ${transcodeDecisionCode}! Expected code 1001.`)
|
||||
console.log(`Error message: '${res.data.MediaContainer.transcodeDecisionText}'`)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
getStatusUrl() {
|
||||
|
||||
@ -105,7 +105,7 @@ async function _writeProgramme(channel, program, xw) {
|
||||
}
|
||||
xw.endElement()
|
||||
// Rating
|
||||
if (typeof program.rating !== 'undefined') {
|
||||
if ( (program.rating != null) && (typeof program.rating !== 'undefined') ) {
|
||||
xw.startElement('rating')
|
||||
xw.writeAttribute('system', 'MPAA')
|
||||
xw.writeElement('value', program.rating)
|
||||
|
||||
@ -146,12 +146,14 @@
|
||||
<div class="col-sm-6">
|
||||
<h6 style="font-weight: bold">Miscellaneous Options</h6>
|
||||
<div class="form-group">
|
||||
<label>Max Direct Stream Bitrate</label>
|
||||
<label>Max Direct Stream Bitrate (Kbps)</label>
|
||||
<input type="text" class="form-control form-control-sm" ng-model="settings.directStreamBitrate" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Max Transcode Bitrate</label>
|
||||
<input type="text" class="form-control form-control-sm" ng-model="settings.transcodeBitrate" />
|
||||
<label>Max Transcode Bitrate (Kbps)</label>
|
||||
<input type="text" class="form-control form-control-sm" ng-model="settings.transcodeBitrate" aria-described-by="transcodebrhelp" />
|
||||
<small id="transcodebrhelp" class='text-muted form-text'>Plex will decide to transcode or direct play based on these settings and if Plex transcodes, it will try to match the transcode bitrate.</small>
|
||||
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Direct Stream Media Buffer Size</label>
|
||||
|
||||
@ -15,11 +15,13 @@
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<label>EPG Cache (hours)</label>
|
||||
<input type="number" class="form-control form-control-sm" ng-model="settings.cache"/>
|
||||
<input type="number" class="form-control form-control-sm" ng-model="settings.cache" aria-describedby="cachehelp"/>
|
||||
<small id="cachehelp" class="form-text text-muted">How many hours of programming to include in the xmltv file.</small>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<label>Refresh Timer (hours)</label>
|
||||
<input type="number" class="form-control form-control-sm" ng-model="settings.refresh"/>
|
||||
<input type="number" class="form-control form-control-sm" ng-model="settings.refresh" aria-describedby="timerhelp"/>
|
||||
<small id="timerhelp" class="form-text text-muted">How often should the xmltv file be updated.</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user