Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | 3x 3x 5x 5x 1x 1x 3x 7x 7x 4x 3x 7x 5x 5x 5x 2x 2x 3x 3x 2x 2x 1x 2x 6x 6x 6x 6x 2x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x | import BinarySearch from './binary-search'; import { logger } from '../utils/logger'; export function findFirstFragWithCC (fragments, cc) { let firstFrag = null; for (let i = 0; i < fragments.length; i += 1) { const currentFrag = fragments[i]; if (currentFrag && currentFrag.cc === cc) { firstFrag = currentFrag; break; } } return firstFrag; } export function findFragWithCC (fragments, CC) { return BinarySearch.search(fragments, (candidate) => { if (candidate.cc < CC) return 1; else if (candidate.cc > CC) return -1; else return 0; }); } export function shouldAlignOnDiscontinuities (lastFrag, lastLevel, details) { let shouldAlign = false; if (lastLevel && lastLevel.details && details) { if (details.endCC > details.startCC || (lastFrag && lastFrag.cc < details.startCC)) shouldAlign = true; } return shouldAlign; } // Find the first frag in the previous level which matches the CC of the first frag of the new level export function findDiscontinuousReferenceFrag (prevDetails, curDetails) { const prevFrags = prevDetails.fragments; const curFrags = curDetails.fragments; if (!curFrags.length || !prevFrags.length) { logger.log('No fragments to align'); return; } const prevStartFrag = findFirstFragWithCC(prevFrags, curFrags[0].cc); if (!prevStartFrag || (prevStartFrag && !prevStartFrag.startPTS)) { logger.log('No frag in previous level to align on'); return; } return prevStartFrag; } export function adjustPts (sliding, details) { details.fragments.forEach((frag) => { Eif (frag) { let start = frag.start + sliding; frag.start = frag.startPTS = start; frag.endPTS = start + frag.duration; } }); details.PTSKnown = true; } // If a change in CC is detected, the PTS can no longer be relied upon // Attempt to align the level by using the last level - find the last frag matching the current CC and use it's PTS // as a reference export function alignDiscontinuities (lastFrag, lastLevel, details) { Eif (shouldAlignOnDiscontinuities(lastFrag, lastLevel, details)) { const referenceFrag = findDiscontinuousReferenceFrag(lastLevel.details, details); Iif (referenceFrag) { logger.log('Adjusting PTS using last level due to CC increase within current level'); adjustPts(referenceFrag.start, details); } } // try to align using programDateTime attribute (if available) Eif (details.PTSKnown === false && lastLevel && lastLevel.details && lastLevel.details.fragments && lastLevel.details.fragments.length) { // if last level sliding is 1000 and its first frag PROGRAM-DATE-TIME is 2017-08-20 1:10:00 AM // and if new details first frag PROGRAM DATE-TIME is 2017-08-20 1:10:08 AM // then we can deduce that playlist B sliding is 1000+8 = 1008s let lastPDT = lastLevel.details.programDateTime; let newPDT = details.programDateTime; // date diff is in ms. frag.start is in seconds let sliding = (newPDT - lastPDT) / 1000 + lastLevel.details.fragments[0].start; Eif (!isNaN(sliding)) { logger.log(`adjusting PTS using programDateTime delta, sliding:${sliding.toFixed(3)}`); adjustPts(sliding, details); } } } |