mirror of
https://github.com/jellyfin/jellyfin-web.git
synced 2024-11-17 19:08:18 -07:00
add tv genre configuration options
This commit is contained in:
parent
81ab24a44c
commit
f13258a120
@ -15,12 +15,12 @@
|
||||
},
|
||||
"devDependencies": {},
|
||||
"ignore": [],
|
||||
"version": "1.4.16",
|
||||
"_release": "1.4.16",
|
||||
"version": "1.4.17",
|
||||
"_release": "1.4.17",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "1.4.16",
|
||||
"commit": "b564ac84f300199b48a8a2338111d6b7609b671b"
|
||||
"tag": "1.4.17",
|
||||
"commit": "26ee95baf54887c88d2aadf768ded7aa75a65fb7"
|
||||
},
|
||||
"_source": "https://github.com/MediaBrowser/emby-webcomponents.git",
|
||||
"_target": "^1.2.0",
|
||||
|
@ -30,7 +30,7 @@
|
||||
|
||||
.inputLabel {
|
||||
display: inline-block;
|
||||
transition: all .25s ease-out;
|
||||
transition: all .2s ease-out;
|
||||
}
|
||||
|
||||
.inputLabel.blank {
|
||||
|
@ -2,10 +2,13 @@
|
||||
|
||||
var EmbyInputPrototype = Object.create(HTMLInputElement.prototype);
|
||||
|
||||
var inputId = 0;
|
||||
|
||||
EmbyInputPrototype.createdCallback = function () {
|
||||
|
||||
if (!this.id) {
|
||||
this.id = 'input' + new Date().getTime();
|
||||
this.id = 'embyinput' + inputId;
|
||||
inputId++;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -103,6 +103,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
var inputId = 0;
|
||||
|
||||
EmbySelectPrototype.createdCallback = function () {
|
||||
|
||||
var parent = this.parentNode;
|
||||
@ -112,8 +114,10 @@
|
||||
parent.replaceChild(div, this);
|
||||
div.appendChild(this);
|
||||
}
|
||||
|
||||
if (!this.id) {
|
||||
this.id = 'select' + new Date().getTime();
|
||||
this.id = 'embyselect' + inputId;
|
||||
inputId++;
|
||||
}
|
||||
|
||||
this.removeEventListener('mousedown', onMouseDown);
|
||||
|
@ -186,7 +186,7 @@
|
||||
|
||||
.channelHeaderCell {
|
||||
border-bottom: .65vh solid #121212 !important;
|
||||
background-size: auto 65.7%;
|
||||
background-size: auto 70%;
|
||||
background-position: 90% center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
@ -234,7 +234,7 @@
|
||||
}
|
||||
|
||||
.layout-tv .channelPrograms, .layout-tv .channelHeaderCell {
|
||||
height: 7.6vh;
|
||||
height: 9vh;
|
||||
}
|
||||
}
|
||||
|
||||
@ -365,13 +365,12 @@
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
.programCell:focus, .channelHeaderCell:focus, .btnSelectDate:focus {
|
||||
background-color: #52B54B;
|
||||
.programCell, .channelHeaderCell, .btnSelectDate {
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
.programCell:focus .programAccent {
|
||||
background-color: transparent !important;
|
||||
.programCell:focus, .channelHeaderCell:focus, .btnSelectDate:focus {
|
||||
background-color: #555;
|
||||
}
|
||||
|
||||
.timerIcon, .seriesTimerIcon {
|
||||
|
@ -307,6 +307,7 @@
|
||||
// but since mobile browsers are often underpowered,
|
||||
// it can help performance to get them out of the markup
|
||||
var showIndicators = window.innerWidth >= 800;
|
||||
showIndicators = false;
|
||||
|
||||
var options = {
|
||||
showHdIcon: showIndicators,
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "hls.js",
|
||||
"version": "0.5.33",
|
||||
"version": "0.5.34",
|
||||
"license": "Apache-2.0",
|
||||
"description": "Media Source Extension - HLS library, by/for Dailymotion",
|
||||
"homepage": "https://github.com/dailymotion/hls.js",
|
||||
@ -16,11 +16,11 @@
|
||||
"test",
|
||||
"tests"
|
||||
],
|
||||
"_release": "0.5.33",
|
||||
"_release": "0.5.34",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v0.5.33",
|
||||
"commit": "bee1aea020de895904cef15962e71c062338e22e"
|
||||
"tag": "v0.5.34",
|
||||
"commit": "fe719c8631da6014babef8c5914f59b1620769a6"
|
||||
},
|
||||
"_source": "git://github.com/dailymotion/hls.js.git",
|
||||
"_target": "~0.5.7",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "hls.js",
|
||||
"version": "0.5.33",
|
||||
"version": "0.5.34",
|
||||
"license": "Apache-2.0",
|
||||
"description": "Media Source Extension - HLS library, by/for Dailymotion",
|
||||
"homepage": "https://github.com/dailymotion/hls.js",
|
||||
|
111
dashboard-ui/bower_components/hls.js/dist/hls.js
vendored
111
dashboard-ui/bower_components/hls.js/dist/hls.js
vendored
@ -2373,7 +2373,7 @@ var StreamController = function (_EventHandler) {
|
||||
var currentLevel = this.levels[this.level],
|
||||
details = currentLevel.details,
|
||||
duration = details.totalduration,
|
||||
start = fragCurrent.start,
|
||||
start = fragCurrent.startDTS !== undefined ? fragCurrent.startDTS : fragCurrent.start,
|
||||
level = fragCurrent.level,
|
||||
sn = fragCurrent.sn,
|
||||
audioCodec = currentLevel.audioCodec || this.config.defaultAudioCodec;
|
||||
@ -2495,7 +2495,7 @@ var StreamController = function (_EventHandler) {
|
||||
|
||||
_logger.logger.log('parsed ' + data.type + ',PTS:[' + data.startPTS.toFixed(3) + ',' + data.endPTS.toFixed(3) + '],DTS:[' + data.startDTS.toFixed(3) + '/' + data.endDTS.toFixed(3) + '],nb:' + data.nb);
|
||||
|
||||
var drift = _levelHelper2.default.updateFragPTS(level.details, frag.sn, data.startPTS, data.endPTS),
|
||||
var drift = _levelHelper2.default.updateFragPTSDTS(level.details, frag.sn, data.startPTS, data.endPTS, data.startDTS, data.endDTS),
|
||||
hls = this.hls;
|
||||
hls.trigger(_events2.default.LEVEL_PTS_UPDATED, { details: level.details, level: this.level, drift: drift });
|
||||
|
||||
@ -2645,7 +2645,7 @@ var StreamController = function (_EventHandler) {
|
||||
_logger.logger.log('target seek position:' + targetSeekPosition);
|
||||
}
|
||||
var bufferInfo = _bufferHelper2.default.bufferInfo(media, currentTime, 0),
|
||||
expectedPlaying = !(media.paused || media.ended || media.seeking || readyState < 2),
|
||||
expectedPlaying = !(media.paused || media.ended || media.seeking || media.buffered.length === 0),
|
||||
jumpThreshold = 0.4,
|
||||
// tolerance needed as some browsers stalls playback before reaching buffered range end
|
||||
playheadMoving = currentTime > media.playbackRate * this.lastCurrentTime;
|
||||
@ -4581,14 +4581,14 @@ var TSDemuxer = function () {
|
||||
value: function switchLevel() {
|
||||
this.pmtParsed = false;
|
||||
this._pmtId = -1;
|
||||
this.lastAacPTS = null;
|
||||
this.aacOverFlow = null;
|
||||
this._avcTrack = { container: 'video/mp2t', type: 'video', id: -1, sequenceNumber: 0, samples: [], len: 0, nbNalu: 0 };
|
||||
this._aacTrack = { container: 'video/mp2t', type: 'audio', id: -1, sequenceNumber: 0, samples: [], len: 0 };
|
||||
this._id3Track = { type: 'id3', id: -1, sequenceNumber: 0, samples: [], len: 0 };
|
||||
this._txtTrack = { type: 'text', id: -1, sequenceNumber: 0, samples: [], len: 0 };
|
||||
// flush any partial content
|
||||
this.aacOverFlow = null;
|
||||
this.aacLastPTS = null;
|
||||
this.avcNaluState = 0;
|
||||
this.remuxer.switchLevel();
|
||||
}
|
||||
}, {
|
||||
@ -4917,6 +4917,22 @@ var TSDemuxer = function () {
|
||||
pes.data = null;
|
||||
var debugString = '';
|
||||
|
||||
var pushAccesUnit = function pushAccesUnit() {
|
||||
if (units2.length) {
|
||||
// only push AVC sample if keyframe already found in this fragment OR
|
||||
// keyframe found in last fragment (track.sps) AND
|
||||
// samples already appended (we already found a keyframe in this fragment) OR fragment is contiguous
|
||||
if (key === true || track.sps && (samples.length || this.contiguous)) {
|
||||
avcSample = { units: { units: units2, length: length }, pts: pes.pts, dts: pes.dts, key: key };
|
||||
samples.push(avcSample);
|
||||
track.len += length;
|
||||
track.nbNalu += units2.length;
|
||||
}
|
||||
units2 = [];
|
||||
length = 0;
|
||||
}
|
||||
};
|
||||
|
||||
units.forEach(function (unit) {
|
||||
switch (unit.type) {
|
||||
//NDR
|
||||
@ -5029,6 +5045,7 @@ var TSDemuxer = function () {
|
||||
if (debug) {
|
||||
debugString += 'AUD ';
|
||||
}
|
||||
pushAccesUnit();
|
||||
break;
|
||||
default:
|
||||
push = false;
|
||||
@ -5043,19 +5060,7 @@ var TSDemuxer = function () {
|
||||
if (debug || debugString.length) {
|
||||
_logger.logger.log(debugString);
|
||||
}
|
||||
//build sample from PES
|
||||
// Annex B to MP4 conversion to be done
|
||||
if (units2.length) {
|
||||
// only push AVC sample if keyframe already found in this fragment OR
|
||||
// keyframe found in last fragment (track.sps) AND
|
||||
// samples already appended (we already found a keyframe in this fragment) OR fragment is contiguous
|
||||
if (key === true || track.sps && (samples.length || this.contiguous)) {
|
||||
avcSample = { units: { units: units2, length: length }, pts: pes.pts, dts: pes.dts, key: key };
|
||||
samples.push(avcSample);
|
||||
track.len += length;
|
||||
track.nbNalu += units2.length;
|
||||
}
|
||||
}
|
||||
pushAccesUnit();
|
||||
}
|
||||
}, {
|
||||
key: '_parseAVCNALu',
|
||||
@ -5064,7 +5069,7 @@ var TSDemuxer = function () {
|
||||
len = array.byteLength,
|
||||
value,
|
||||
overflow,
|
||||
state = 0;
|
||||
state = this.avcNaluState;
|
||||
var units = [],
|
||||
unit,
|
||||
unitType,
|
||||
@ -5099,22 +5104,45 @@ var TSDemuxer = function () {
|
||||
//logger.log('pushing NALU, type/size:' + unit.type + '/' + unit.data.byteLength);
|
||||
units.push(unit);
|
||||
} else {
|
||||
// If NAL units are not starting right at the beginning of the PES packet, push preceding data into previous NAL unit.
|
||||
overflow = i - state - 1;
|
||||
if (overflow) {
|
||||
// lastUnitStart is undefined => this is the first start code found in this PES packet
|
||||
// first check if start code delimiter is overlapping between 2 PES packets,
|
||||
// ie it started in last packet (lastState not zero)
|
||||
// and ended at the beginning of this PES packet (i <= 4 - lastState)
|
||||
var lastState = this.avcNaluState;
|
||||
if (lastState && i <= 4 - lastState) {
|
||||
// start delimiter overlapping between PES packets
|
||||
// strip start delimiter bytes from the end of last NAL unit
|
||||
var track = this._avcTrack,
|
||||
samples = track.samples;
|
||||
//logger.log('first NALU found with overflow:' + overflow);
|
||||
if (samples.length) {
|
||||
var lastavcSample = samples[samples.length - 1],
|
||||
lastUnits = lastavcSample.units.units,
|
||||
lastUnit = lastUnits[lastUnits.length - 1],
|
||||
tmp = new Uint8Array(lastUnit.data.byteLength + overflow);
|
||||
tmp.set(lastUnit.data, 0);
|
||||
tmp.set(array.subarray(0, overflow), lastUnit.data.byteLength);
|
||||
lastUnit.data = tmp;
|
||||
lastavcSample.units.length += overflow;
|
||||
track.len += overflow;
|
||||
lastUnit = lastUnits[lastUnits.length - 1];
|
||||
// check if lastUnit had a state different from zero
|
||||
if (lastUnit.state) {
|
||||
// strip last bytes
|
||||
lastUnit.data = lastUnit.data.subarray(0, lastUnit.data.byteLength - lastState);
|
||||
lastavcSample.units.length -= lastState;
|
||||
track.len -= lastState;
|
||||
}
|
||||
}
|
||||
}
|
||||
// If NAL units are not starting right at the beginning of the PES packet, push preceding data into previous NAL unit.
|
||||
overflow = i - state - 1;
|
||||
if (overflow > 0) {
|
||||
var _track = this._avcTrack,
|
||||
_samples = _track.samples;
|
||||
//logger.log('first NALU found with overflow:' + overflow);
|
||||
if (_samples.length) {
|
||||
var _lastavcSample = _samples[_samples.length - 1],
|
||||
_lastUnits = _lastavcSample.units.units,
|
||||
_lastUnit = _lastUnits[_lastUnits.length - 1],
|
||||
tmp = new Uint8Array(_lastUnit.data.byteLength + overflow);
|
||||
tmp.set(_lastUnit.data, 0);
|
||||
tmp.set(array.subarray(0, overflow), _lastUnit.data.byteLength);
|
||||
_lastUnit.data = tmp;
|
||||
_lastavcSample.units.length += overflow;
|
||||
_track.len += overflow;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5130,9 +5158,10 @@ var TSDemuxer = function () {
|
||||
}
|
||||
}
|
||||
if (lastUnitStart) {
|
||||
unit = { data: array.subarray(lastUnitStart, len), type: lastUnitType };
|
||||
unit = { data: array.subarray(lastUnitStart, len), type: lastUnitType, state: state };
|
||||
units.push(unit);
|
||||
//logger.log('pushing NALU, type/size:' + unit.type + '/' + unit.data.byteLength);
|
||||
//logger.log('pushing NALU, type/size/state:' + unit.type + '/' + unit.data.byteLength + '/' + state);
|
||||
this.avcNaluState = state;
|
||||
}
|
||||
return units;
|
||||
}
|
||||
@ -5146,7 +5175,7 @@ var TSDemuxer = function () {
|
||||
duration = this._duration,
|
||||
audioCodec = this.audioCodec,
|
||||
aacOverFlow = this.aacOverFlow,
|
||||
lastAacPTS = this.lastAacPTS,
|
||||
aacLastPTS = this.aacLastPTS,
|
||||
config,
|
||||
frameLength,
|
||||
frameDuration,
|
||||
@ -5198,8 +5227,8 @@ var TSDemuxer = function () {
|
||||
|
||||
// if last AAC frame is overflowing, we should ensure timestamps are contiguous:
|
||||
// first sample PTS should be equal to last sample PTS + frameDuration
|
||||
if (aacOverFlow && lastAacPTS) {
|
||||
var newPTS = lastAacPTS + frameDuration;
|
||||
if (aacOverFlow && aacLastPTS) {
|
||||
var newPTS = aacLastPTS + frameDuration;
|
||||
if (Math.abs(newPTS - pts) > 1) {
|
||||
_logger.logger.log('AAC: align PTS for overlapping frames by ' + Math.round((newPTS - pts) / 90));
|
||||
pts = newPTS;
|
||||
@ -5239,7 +5268,7 @@ var TSDemuxer = function () {
|
||||
aacOverFlow = null;
|
||||
}
|
||||
this.aacOverFlow = aacOverFlow;
|
||||
this.lastAacPTS = stamp;
|
||||
this.aacLastPTS = stamp;
|
||||
}
|
||||
}, {
|
||||
key: '_parseID3PES',
|
||||
@ -5667,7 +5696,7 @@ var LevelHelper = function () {
|
||||
|
||||
// if at least one fragment contains PTS info, recompute PTS information for all fragments
|
||||
if (PTSFrag) {
|
||||
LevelHelper.updateFragPTS(newDetails, PTSFrag.sn, PTSFrag.startPTS, PTSFrag.endPTS);
|
||||
LevelHelper.updateFragPTSDTS(newDetails, PTSFrag.sn, PTSFrag.startPTS, PTSFrag.endPTS, PTSFrag.startDTS, PTSFrag.endDTS);
|
||||
} else {
|
||||
// ensure that delta is within oldfragments range
|
||||
// also adjust sliding in case delta is 0 (we could have old=[50-60] and new=old=[50-61])
|
||||
@ -5686,8 +5715,8 @@ var LevelHelper = function () {
|
||||
return;
|
||||
}
|
||||
}, {
|
||||
key: 'updateFragPTS',
|
||||
value: function updateFragPTS(details, sn, startPTS, endPTS) {
|
||||
key: 'updateFragPTSDTS',
|
||||
value: function updateFragPTSDTS(details, sn, startPTS, endPTS, startDTS, endDTS) {
|
||||
var fragIdx, fragments, frag, i;
|
||||
// exit if sn out of range
|
||||
if (sn < details.startSN || sn > details.endSN) {
|
||||
@ -5699,12 +5728,16 @@ var LevelHelper = function () {
|
||||
if (!isNaN(frag.startPTS)) {
|
||||
startPTS = Math.min(startPTS, frag.startPTS);
|
||||
endPTS = Math.max(endPTS, frag.endPTS);
|
||||
startDTS = Math.min(startDTS, frag.startDTS);
|
||||
endDTS = Math.max(endDTS, frag.endDTS);
|
||||
}
|
||||
|
||||
var drift = startPTS - frag.start;
|
||||
|
||||
frag.start = frag.startPTS = startPTS;
|
||||
frag.endPTS = endPTS;
|
||||
frag.startDTS = startDTS;
|
||||
frag.endDTS = endDTS;
|
||||
frag.duration = endPTS - startPTS;
|
||||
// adjust fragment PTS/duration from seqnum-1 to frag 0
|
||||
for (i = fragIdx; i > 0; i--) {
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "hls.js",
|
||||
"version": "0.5.33",
|
||||
"version": "0.5.34",
|
||||
"license": "Apache-2.0",
|
||||
"description": "Media Source Extension - HLS library, by/for Dailymotion",
|
||||
"homepage": "https://github.com/dailymotion/hls.js",
|
||||
@ -19,7 +19,7 @@
|
||||
"prebuild": "npm run clean & npm run test",
|
||||
"build": "npm run babel && browserify -t [babelify] -s Hls src/index.js --debug | exorcist dist/hls.js.map -b . > dist/hls.js",
|
||||
"postbuild": "npm run minify",
|
||||
"prerelease": "npm run prebuild && npm run build && npm run postbuild && git add dist/* && git commit -m 'update dist'",
|
||||
"prerelease": "npm run prebuild && npm run build && npm run postbuild && git add --ignore-errors dist/* && git commit -m 'update dist'",
|
||||
"patch": "npm run prerelease && mversion p",
|
||||
"minor": "npm run prerelease && mversion mi",
|
||||
"major": "npm run prerelease && mversion ma",
|
||||
|
@ -764,7 +764,7 @@ class StreamController extends EventHandler {
|
||||
var currentLevel = this.levels[this.level],
|
||||
details = currentLevel.details,
|
||||
duration = details.totalduration,
|
||||
start = fragCurrent.start,
|
||||
start = fragCurrent.startDTS !== undefined ? fragCurrent.startDTS : fragCurrent.start,
|
||||
level = fragCurrent.level,
|
||||
sn = fragCurrent.sn,
|
||||
audioCodec = currentLevel.audioCodec || this.config.defaultAudioCodec;
|
||||
@ -880,7 +880,7 @@ class StreamController extends EventHandler {
|
||||
|
||||
logger.log(`parsed ${data.type},PTS:[${data.startPTS.toFixed(3)},${data.endPTS.toFixed(3)}],DTS:[${data.startDTS.toFixed(3)}/${data.endDTS.toFixed(3)}],nb:${data.nb}`);
|
||||
|
||||
var drift = LevelHelper.updateFragPTS(level.details,frag.sn,data.startPTS,data.endPTS),
|
||||
var drift = LevelHelper.updateFragPTSDTS(level.details,frag.sn,data.startPTS,data.endPTS,data.startDTS,data.endDTS),
|
||||
hls = this.hls;
|
||||
hls.trigger(Event.LEVEL_PTS_UPDATED, {details: level.details, level: this.level, drift: drift});
|
||||
|
||||
@ -1024,7 +1024,7 @@ _checkBuffer() {
|
||||
logger.log(`target seek position:${targetSeekPosition}`);
|
||||
}
|
||||
var bufferInfo = BufferHelper.bufferInfo(media,currentTime,0),
|
||||
expectedPlaying = !(media.paused || media.ended || media.seeking || readyState < 2),
|
||||
expectedPlaying = !(media.paused || media.ended || media.seeking || media.buffered.length === 0),
|
||||
jumpThreshold = 0.4, // tolerance needed as some browsers stalls playback before reaching buffered range end
|
||||
playheadMoving = currentTime > media.playbackRate*this.lastCurrentTime;
|
||||
|
||||
|
@ -37,14 +37,14 @@
|
||||
switchLevel() {
|
||||
this.pmtParsed = false;
|
||||
this._pmtId = -1;
|
||||
this.lastAacPTS = null;
|
||||
this.aacOverFlow = null;
|
||||
this._avcTrack = {container : 'video/mp2t', type: 'video', id :-1, sequenceNumber: 0, samples : [], len : 0, nbNalu : 0};
|
||||
this._aacTrack = {container : 'video/mp2t', type: 'audio', id :-1, sequenceNumber: 0, samples : [], len : 0};
|
||||
this._id3Track = {type: 'id3', id :-1, sequenceNumber: 0, samples : [], len : 0};
|
||||
this._txtTrack = {type: 'text', id: -1, sequenceNumber: 0, samples: [], len: 0};
|
||||
// flush any partial content
|
||||
this.aacOverFlow = null;
|
||||
this.aacLastPTS = null;
|
||||
this.avcNaluState = 0;
|
||||
this.remuxer.switchLevel();
|
||||
}
|
||||
|
||||
@ -344,6 +344,23 @@
|
||||
pes.data = null;
|
||||
var debugString = '';
|
||||
|
||||
var pushAccesUnit = function() {
|
||||
if (units2.length) {
|
||||
// only push AVC sample if keyframe already found in this fragment OR
|
||||
// keyframe found in last fragment (track.sps) AND
|
||||
// samples already appended (we already found a keyframe in this fragment) OR fragment is contiguous
|
||||
if (key === true ||
|
||||
(track.sps && (samples.length || this.contiguous))) {
|
||||
avcSample = {units: { units : units2, length : length}, pts: pes.pts, dts: pes.dts, key: key};
|
||||
samples.push(avcSample);
|
||||
track.len += length;
|
||||
track.nbNalu += units2.length;
|
||||
}
|
||||
units2 = [];
|
||||
length = 0;
|
||||
}
|
||||
};
|
||||
|
||||
units.forEach(unit => {
|
||||
switch(unit.type) {
|
||||
//NDR
|
||||
@ -463,6 +480,7 @@
|
||||
if(debug) {
|
||||
debugString += 'AUD ';
|
||||
}
|
||||
pushAccesUnit();
|
||||
break;
|
||||
default:
|
||||
push = false;
|
||||
@ -477,25 +495,12 @@
|
||||
if(debug || debugString.length) {
|
||||
logger.log(debugString);
|
||||
}
|
||||
//build sample from PES
|
||||
// Annex B to MP4 conversion to be done
|
||||
if (units2.length) {
|
||||
// only push AVC sample if keyframe already found in this fragment OR
|
||||
// keyframe found in last fragment (track.sps) AND
|
||||
// samples already appended (we already found a keyframe in this fragment) OR fragment is contiguous
|
||||
if (key === true ||
|
||||
(track.sps && (samples.length || this.contiguous))) {
|
||||
avcSample = {units: { units : units2, length : length}, pts: pes.pts, dts: pes.dts, key: key};
|
||||
samples.push(avcSample);
|
||||
track.len += length;
|
||||
track.nbNalu += units2.length;
|
||||
}
|
||||
}
|
||||
pushAccesUnit();
|
||||
}
|
||||
|
||||
|
||||
_parseAVCNALu(array) {
|
||||
var i = 0, len = array.byteLength, value, overflow, state = 0;
|
||||
var i = 0, len = array.byteLength, value, overflow, state = this.avcNaluState;
|
||||
var units = [], unit, unitType, lastUnitStart, lastUnitType;
|
||||
//logger.log('PES:' + Hex.hexDump(array));
|
||||
while (i < len) {
|
||||
@ -526,14 +531,37 @@
|
||||
//logger.log('pushing NALU, type/size:' + unit.type + '/' + unit.data.byteLength);
|
||||
units.push(unit);
|
||||
} else {
|
||||
// lastUnitStart is undefined => this is the first start code found in this PES packet
|
||||
// first check if start code delimiter is overlapping between 2 PES packets,
|
||||
// ie it started in last packet (lastState not zero)
|
||||
// and ended at the beginning of this PES packet (i <= 4 - lastState)
|
||||
let lastState = this.avcNaluState;
|
||||
if(lastState && (i <= 4 - lastState)) {
|
||||
// start delimiter overlapping between PES packets
|
||||
// strip start delimiter bytes from the end of last NAL unit
|
||||
let track = this._avcTrack,
|
||||
samples = track.samples;
|
||||
if (samples.length) {
|
||||
let lastavcSample = samples[samples.length - 1],
|
||||
lastUnits = lastavcSample.units.units,
|
||||
lastUnit = lastUnits[lastUnits.length - 1];
|
||||
// check if lastUnit had a state different from zero
|
||||
if (lastUnit.state) {
|
||||
// strip last bytes
|
||||
lastUnit.data = lastUnit.data.subarray(0,lastUnit.data.byteLength - lastState);
|
||||
lastavcSample.units.length -= lastState;
|
||||
track.len -= lastState;
|
||||
}
|
||||
}
|
||||
}
|
||||
// If NAL units are not starting right at the beginning of the PES packet, push preceding data into previous NAL unit.
|
||||
overflow = i - state - 1;
|
||||
if (overflow) {
|
||||
var track = this._avcTrack,
|
||||
if (overflow > 0) {
|
||||
let track = this._avcTrack,
|
||||
samples = track.samples;
|
||||
//logger.log('first NALU found with overflow:' + overflow);
|
||||
if (samples.length) {
|
||||
var lastavcSample = samples[samples.length - 1],
|
||||
let lastavcSample = samples[samples.length - 1],
|
||||
lastUnits = lastavcSample.units.units,
|
||||
lastUnit = lastUnits[lastUnits.length - 1],
|
||||
tmp = new Uint8Array(lastUnit.data.byteLength + overflow);
|
||||
@ -557,9 +585,10 @@
|
||||
}
|
||||
}
|
||||
if (lastUnitStart) {
|
||||
unit = {data: array.subarray(lastUnitStart, len), type: lastUnitType};
|
||||
unit = {data: array.subarray(lastUnitStart, len), type: lastUnitType, state : state};
|
||||
units.push(unit);
|
||||
//logger.log('pushing NALU, type/size:' + unit.type + '/' + unit.data.byteLength);
|
||||
//logger.log('pushing NALU, type/size/state:' + unit.type + '/' + unit.data.byteLength + '/' + state);
|
||||
this.avcNaluState = state;
|
||||
}
|
||||
return units;
|
||||
}
|
||||
@ -572,7 +601,7 @@
|
||||
duration = this._duration,
|
||||
audioCodec = this.audioCodec,
|
||||
aacOverFlow = this.aacOverFlow,
|
||||
lastAacPTS = this.lastAacPTS,
|
||||
aacLastPTS = this.aacLastPTS,
|
||||
config, frameLength, frameDuration, frameIndex, offset, headerLength, stamp, len, aacSample;
|
||||
if (aacOverFlow) {
|
||||
var tmp = new Uint8Array(aacOverFlow.byteLength + data.byteLength);
|
||||
@ -616,8 +645,8 @@
|
||||
|
||||
// if last AAC frame is overflowing, we should ensure timestamps are contiguous:
|
||||
// first sample PTS should be equal to last sample PTS + frameDuration
|
||||
if(aacOverFlow && lastAacPTS) {
|
||||
var newPTS = lastAacPTS+frameDuration;
|
||||
if(aacOverFlow && aacLastPTS) {
|
||||
var newPTS = aacLastPTS+frameDuration;
|
||||
if(Math.abs(newPTS-pts) > 1) {
|
||||
logger.log(`AAC: align PTS for overlapping frames by ${Math.round((newPTS-pts)/90)}`);
|
||||
pts=newPTS;
|
||||
@ -659,7 +688,7 @@
|
||||
aacOverFlow = null;
|
||||
}
|
||||
this.aacOverFlow = aacOverFlow;
|
||||
this.lastAacPTS = stamp;
|
||||
this.aacLastPTS = stamp;
|
||||
}
|
||||
|
||||
_parseID3PES(pes) {
|
||||
|
@ -42,7 +42,7 @@ class LevelHelper {
|
||||
|
||||
// if at least one fragment contains PTS info, recompute PTS information for all fragments
|
||||
if(PTSFrag) {
|
||||
LevelHelper.updateFragPTS(newDetails,PTSFrag.sn,PTSFrag.startPTS,PTSFrag.endPTS);
|
||||
LevelHelper.updateFragPTSDTS(newDetails,PTSFrag.sn,PTSFrag.startPTS,PTSFrag.endPTS,PTSFrag.startDTS,PTSFrag.endDTS);
|
||||
} else {
|
||||
// ensure that delta is within oldfragments range
|
||||
// also adjust sliding in case delta is 0 (we could have old=[50-60] and new=old=[50-61])
|
||||
@ -61,7 +61,7 @@ class LevelHelper {
|
||||
return;
|
||||
}
|
||||
|
||||
static updateFragPTS(details,sn,startPTS,endPTS) {
|
||||
static updateFragPTSDTS(details,sn,startPTS,endPTS,startDTS,endDTS) {
|
||||
var fragIdx, fragments, frag, i;
|
||||
// exit if sn out of range
|
||||
if (sn < details.startSN || sn > details.endSN) {
|
||||
@ -73,12 +73,16 @@ class LevelHelper {
|
||||
if(!isNaN(frag.startPTS)) {
|
||||
startPTS = Math.min(startPTS,frag.startPTS);
|
||||
endPTS = Math.max(endPTS, frag.endPTS);
|
||||
startDTS = Math.min(startDTS,frag.startDTS);
|
||||
endDTS = Math.max(endDTS, frag.endDTS);
|
||||
}
|
||||
|
||||
var drift = startPTS - frag.start;
|
||||
|
||||
frag.start = frag.startPTS = startPTS;
|
||||
frag.endPTS = endPTS;
|
||||
frag.startDTS = startDTS;
|
||||
frag.endDTS = endDTS;
|
||||
frag.duration = endPTS - startPTS;
|
||||
// adjust fragment PTS/duration from seqnum-1 to frag 0
|
||||
for(i = fragIdx ; i > 0 ; i--) {
|
||||
|
@ -30,14 +30,14 @@
|
||||
"web-component-tester": "polymer/web-component-tester#^3.4.0"
|
||||
},
|
||||
"ignore": [],
|
||||
"homepage": "https://github.com/PolymerElements/iron-a11y-announcer",
|
||||
"homepage": "https://github.com/polymerelements/iron-a11y-announcer",
|
||||
"_release": "1.0.4",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v1.0.4",
|
||||
"commit": "5ce3eb8c4282bb53cd72e348858dc6be6b4c50b9"
|
||||
},
|
||||
"_source": "git://github.com/PolymerElements/iron-a11y-announcer.git",
|
||||
"_source": "git://github.com/polymerelements/iron-a11y-announcer.git",
|
||||
"_target": "^1.0.0",
|
||||
"_originalSource": "PolymerElements/iron-a11y-announcer"
|
||||
"_originalSource": "polymerelements/iron-a11y-announcer"
|
||||
}
|
@ -26,14 +26,14 @@
|
||||
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
|
||||
},
|
||||
"main": "iron-meta.html",
|
||||
"homepage": "https://github.com/polymerelements/iron-meta",
|
||||
"homepage": "https://github.com/PolymerElements/iron-meta",
|
||||
"_release": "1.1.1",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v1.1.1",
|
||||
"commit": "e171ee234b482219c9514e6f9551df48ef48bd9f"
|
||||
},
|
||||
"_source": "git://github.com/polymerelements/iron-meta.git",
|
||||
"_source": "git://github.com/PolymerElements/iron-meta.git",
|
||||
"_target": "^1.0.0",
|
||||
"_originalSource": "polymerelements/iron-meta"
|
||||
"_originalSource": "PolymerElements/iron-meta"
|
||||
}
|
@ -28,14 +28,14 @@
|
||||
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
|
||||
},
|
||||
"ignore": [],
|
||||
"homepage": "https://github.com/PolymerElements/iron-resizable-behavior",
|
||||
"homepage": "https://github.com/polymerelements/iron-resizable-behavior",
|
||||
"_release": "1.0.3",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v1.0.3",
|
||||
"commit": "dda1df6aaf452aedf3e52ff0cf69e72439452216"
|
||||
},
|
||||
"_source": "git://github.com/PolymerElements/iron-resizable-behavior.git",
|
||||
"_source": "git://github.com/polymerelements/iron-resizable-behavior.git",
|
||||
"_target": "^1.0.0",
|
||||
"_originalSource": "PolymerElements/iron-resizable-behavior"
|
||||
"_originalSource": "polymerelements/iron-resizable-behavior"
|
||||
}
|
@ -39,6 +39,6 @@
|
||||
"commit": "ce5b9fb2d8aa03c698410e2e55cffcfa0b788a3a"
|
||||
},
|
||||
"_source": "git://github.com/Polymer/polymer.git",
|
||||
"_target": "^1.0.0",
|
||||
"_target": "^1.1.0",
|
||||
"_originalSource": "Polymer/polymer"
|
||||
}
|
@ -1,34 +1,53 @@
|
||||
define(['jQuery', 'paper-checkbox', 'paper-button', 'paper-input', 'paper-item-body', 'paper-icon-item'], function ($) {
|
||||
define(['jQuery', 'paper-checkbox', 'paper-button', 'emby-input', 'paper-item-body', 'paper-icon-item'], function ($) {
|
||||
|
||||
return function (page, providerId, options) {
|
||||
|
||||
var self = this;
|
||||
|
||||
function getListingProvider(config, id) {
|
||||
|
||||
if (config && id) {
|
||||
return config.ListingProviders.filter(function (i) {
|
||||
return i.Id == id;
|
||||
})[0] || getListingProvider();
|
||||
}
|
||||
|
||||
return ApiClient.getJSON(ApiClient.getUrl('LiveTv/ListingProviders/Default'));
|
||||
}
|
||||
|
||||
function reload() {
|
||||
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
ApiClient.getNamedConfiguration("livetv").then(function (config) {
|
||||
|
||||
var info = config.ListingProviders.filter(function (i) {
|
||||
return i.Id == providerId;
|
||||
})[0] || {};
|
||||
getListingProvider(config, providerId).then(function (info) {
|
||||
page.querySelector('.txtPath').value = info.Path || '';
|
||||
page.querySelector('.txtKids').value = (info.KidsGenres || []).join('|');
|
||||
page.querySelector('.txtNews').value = (info.NewsGenres || []).join('|');
|
||||
page.querySelector('.txtSports').value = (info.SportsGenres || []).join('|');
|
||||
|
||||
page.querySelector('.txtPath').value = info.Path || '';
|
||||
page.querySelector('.chkAllTuners').checked = info.EnableAllTuners;
|
||||
|
||||
page.querySelector('.chkAllTuners').checked = info.EnableAllTuners;
|
||||
if (page.querySelector('.chkAllTuners').checked) {
|
||||
page.querySelector('.selectTunersSection').classList.add('hide');
|
||||
} else {
|
||||
page.querySelector('.selectTunersSection').classList.remove('hide');
|
||||
}
|
||||
|
||||
if (page.querySelector('.chkAllTuners').checked) {
|
||||
page.querySelector('.selectTunersSection').classList.add('hide');
|
||||
} else {
|
||||
page.querySelector('.selectTunersSection').classList.remove('hide');
|
||||
}
|
||||
|
||||
refreshTunerDevices(page, info, config.TunerHosts);
|
||||
Dashboard.hideLoadingMsg();
|
||||
refreshTunerDevices(page, info, config.TunerHosts);
|
||||
Dashboard.hideLoadingMsg();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function getGenres(txtInput) {
|
||||
|
||||
var value = txtInput.value;
|
||||
|
||||
return value ? value.split('|') : [];
|
||||
}
|
||||
|
||||
function submitListingsForm() {
|
||||
|
||||
Dashboard.showLoadingMsg();
|
||||
@ -42,7 +61,13 @@
|
||||
})[0] || {};
|
||||
|
||||
info.Type = 'xmltv';
|
||||
|
||||
info.Path = page.querySelector('.txtPath').value;
|
||||
|
||||
info.KidsGenres = getGenres(page.querySelector('.txtKids'));
|
||||
info.NewsGenres = getGenres(page.querySelector('.txtNews'));
|
||||
info.SportsGenres = getGenres(page.querySelector('.txtSports'));
|
||||
|
||||
info.EnableAllTuners = page.querySelector('.chkAllTuners').checked;
|
||||
info.EnabledTuners = info.EnableAllTuners ? [] : $('.chkTuner', page).get().filter(function (i) {
|
||||
return i.checked;
|
||||
|
@ -2,25 +2,39 @@
|
||||
|
||||
<form>
|
||||
<div>
|
||||
<div>
|
||||
<paper-input class="txtPath" label="${LabelPath}" required="required" autocomplete="off"></paper-input>
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" class="txtPath" label="${LabelPath}" required="required" autocomplete="off" />
|
||||
</div>
|
||||
<div>
|
||||
<br />
|
||||
<paper-checkbox class="chkAllTuners">${OptionEnableForAllTuners}</paper-checkbox>
|
||||
<div class="selectTunersSection hide">
|
||||
<br /><br />
|
||||
<div class="paperListLabel">${HeaderTuners}</div>
|
||||
<div class="paperCheckboxList paperList tunerList">
|
||||
</div>
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" class="txtKids" label="${LabelKidsGenres}" autocomplete="off" />
|
||||
<div class="fieldDescription">${XmlTvKidsGenresHelp}</div>
|
||||
</div>
|
||||
<br /><br />
|
||||
<div>
|
||||
<button type="submit" data-role="none" class="clearButton btnSubmitListingsContainer">
|
||||
<paper-button raised class="submit block btnSubmitListings hide"><iron-icon icon="check"></iron-icon><span>${ButtonSave}</span></paper-button>
|
||||
</button>
|
||||
<paper-button raised class="cancel block btnCancel hide" onclick="history.back();"><iron-icon icon="close"></iron-icon><span>${ButtonCancel}</span></paper-button>
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" class="txtNews" label="${LabelNewsGenres}" autocomplete="off" />
|
||||
<div class="fieldDescription"></div>
|
||||
<div class="fieldDescription">${XmlTvNewsGenresHelp}</div>
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" class="txtSports" label="${LabelSportsGenres}" autocomplete="off" />
|
||||
<div class="fieldDescription">${XmlTvSportsGenresHelp}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<br />
|
||||
<paper-checkbox class="chkAllTuners">${OptionEnableForAllTuners}</paper-checkbox>
|
||||
<div class="selectTunersSection hide">
|
||||
<br /><br />
|
||||
<div class="paperListLabel">${HeaderTuners}</div>
|
||||
<div class="paperCheckboxList paperList tunerList">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br /><br />
|
||||
<div>
|
||||
<button type="submit" data-role="none" class="clearButton btnSubmitListingsContainer">
|
||||
<paper-button raised class="submit block btnSubmitListings hide"><iron-icon icon="check"></iron-icon><span>${ButtonSave}</span></paper-button>
|
||||
</button>
|
||||
<paper-button raised class="cancel block btnCancel hide" onclick="history.back();"><iron-icon icon="close"></iron-icon><span>${ButtonCancel}</span></paper-button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
@ -6,7 +6,7 @@
|
||||
<br />
|
||||
<div>
|
||||
|
||||
<paper-button raised class="btnRefresh"><iron-icon icon="refresh"></iron-icon><span>${ButtonScanLibrary}</span></paper-button>
|
||||
<paper-button raised class="btnRefresh subdued"><iron-icon icon="refresh"></iron-icon><span>${ButtonScanLibrary}</span></paper-button>
|
||||
<progress max="100" min="0" style="display: inline-block; vertical-align: middle;" class="refreshProgress"></progress>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -31,7 +31,7 @@
|
||||
</div>
|
||||
<div>
|
||||
|
||||
<paper-button raised class="btnRefresh block"><iron-icon icon="refresh"></iron-icon><span>${ButtonRefreshGuideData}</span></paper-button>
|
||||
<paper-button raised class="btnRefresh block subdued"><iron-icon icon="refresh"></iron-icon><span>${ButtonRefreshGuideData}</span></paper-button>
|
||||
<progress max="100" min="0" style="width: 100%;" class="refreshGuideProgress"></progress>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -2357,5 +2357,11 @@
|
||||
"HeaderHealthMonitor": "Health Monitor",
|
||||
"HealthMonitorNoAlerts": "There are no active alerts.",
|
||||
"RecordingPathChangeMessage": "Changing your recording folder will not migrate existing recordings from the old location to the new. You'll need to move them manually if desired.",
|
||||
"VisualLoginFormHelp": "Select a user or sign in manually"
|
||||
"VisualLoginFormHelp": "Select a user or sign in manually",
|
||||
"LabelSportsGenres": "Sports genres:",
|
||||
"XmlTvSportsGenresHelp": "Programs with these genres will be categorized as sports programs. Separate multiple with '|'.",
|
||||
"LabelNewsGenres": "News genres:",
|
||||
"XmlTvNewsGenresHelp": "Programs with these genres will be categorized as news programs. Separate multiple with '|'.",
|
||||
"LabelKidsGenres": "Children's genres:",
|
||||
"XmlTvKidsGenresHelp": "Programs with these genres will be categorized as programs for children. Separate multiple with '|'."
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user