# All files / src/demux demuxer-inline.js

18% Statements 9/50
3.57% Branches 1/28
40% Functions 2/5
18% Lines 9/50

    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
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120

    15x

    15x
    15x

    3x
    3x
    3x
    3x

    1x
    1x

     /**
     *
     * inline demuxer: probe fragments and instantiate
     * appropriate demuxer depending on content type (TSDemuxer, AACDemuxer, ...)
     *
     */

    import Event from '../events';
    import { ErrorTypes, ErrorDetails } from '../errors';
    import Decrypter from '../crypt/decrypter';
    import AACDemuxer from '../demux/aacdemuxer';
    import MP4Demuxer from '../demux/mp4demuxer';
    import TSDemuxer from '../demux/tsdemuxer';
    import MP3Demuxer from '../demux/mp3demuxer';
    import MP4Remuxer from '../remux/mp4-remuxer';
    import PassThroughRemuxer from '../remux/passthrough-remuxer';

    import { getSelfScope } from '../utils/get-self-scope';
    import { logger } from '../utils/logger';

    // see https://stackoverflow.com/a/11237259/589493
    const global = getSelfScope(); // safeguard for code that might run both on worker and main thread

    let now;
    // performance.now() not available on WebWorker, at least on Safari Desktop
    try {
      now = global.performance.now.bind(global.performance);
    } catch (err) {
      logger.debug('Unable to use Performance API on this environment');
      now = global.Date.now;
    }

    class DemuxerInline {
      constructor (observer, typeSupported, config, vendor) {
        this.observer = observer;
        this.typeSupported = typeSupported;
        this.config = config;
        this.vendor = vendor;
      }

      destroy () {
        let demuxer = this.demuxer;
        Iif (demuxer) {
          demuxer.destroy();
        }
      }

      push (data, decryptdata, initSegment, audioCodec, videoCodec, timeOffset, discontinuity, trackSwitch, contiguous, duration, accurateTimeOffset, defaultInitPTS) {
        if ((data.byteLength > 0) && (decryptdata != null) && (decryptdata.key != null) && (decryptdata.method === 'AES-128')) {
          let decrypter = this.decrypter;
          if (decrypter == null) {
            decrypter = this.decrypter = new Decrypter(this.observer, this.config);
          }

          const startTime = now();
          decrypter.decrypt(data, decryptdata.key.buffer, decryptdata.iv.buffer, (decryptedData) => {
            const endTime = now();
            this.observer.trigger(Event.FRAG_DECRYPTED, { stats: { tstart: startTime, tdecrypt: endTime } });
            this.pushDecrypted(new Uint8Array(decryptedData), decryptdata, new Uint8Array(initSegment), audioCodec, videoCodec, timeOffset, discontinuity, trackSwitch, contiguous, duration, accurateTimeOffset, defaultInitPTS);
          });
        } else {
          this.pushDecrypted(new Uint8Array(data), decryptdata, new Uint8Array(initSegment), audioCodec, videoCodec, timeOffset, discontinuity, trackSwitch, contiguous, duration, accurateTimeOffset, defaultInitPTS);
        }
      }

      pushDecrypted (data, decryptdata, initSegment, audioCodec, videoCodec, timeOffset, discontinuity, trackSwitch, contiguous, duration, accurateTimeOffset, defaultInitPTS) {
        let demuxer = this.demuxer;
        if (!demuxer ||
          // in case of continuity change, or track switch
          // we might switch from content type (AAC container to TS container, or TS to fmp4 for example)
          // so let's check that current demuxer is still valid
          ((discontinuity || trackSwitch) && !this.probe(data))) {
          const observer = this.observer;
          const typeSupported = this.typeSupported;
          const config = this.config;
          // probing order is TS/AAC/MP3/MP4
          const muxConfig = [
            { demux: TSDemuxer, remux: MP4Remuxer },
            { demux: MP4Demuxer, remux: PassThroughRemuxer },
            { demux: AACDemuxer, remux: MP4Remuxer },
            { demux: MP3Demuxer, remux: MP4Remuxer }
          ];

          // probe for content type
          for (let i = 0, len = muxConfig.length; i < len; i++) {
            const mux = muxConfig[i];
            const probe = mux.demux.probe;
            if (probe(data)) {
              const remuxer = this.remuxer = new mux.remux(observer, config, typeSupported, this.vendor);
              demuxer = new mux.demux(observer, remuxer, config, typeSupported);
              this.probe = probe;
              break;
            }
          }
          if (!demuxer) {
            observer.trigger(Event.ERROR, { type: ErrorTypes.MEDIA_ERROR, details: ErrorDetails.FRAG_PARSING_ERROR, fatal: true, reason: 'no demux matching with content found' });
            return;
          }
          this.demuxer = demuxer;
        }
        const remuxer = this.remuxer;

        if (discontinuity || trackSwitch) {
          demuxer.resetInitSegment(initSegment, audioCodec, videoCodec, duration);
          remuxer.resetInitSegment();
        }
        if (discontinuity) {
          demuxer.resetTimeStamp(defaultInitPTS);
          remuxer.resetTimeStamp(defaultInitPTS);
        }
        if (typeof demuxer.setDecryptData === 'function') {
          demuxer.setDecryptData(decryptdata);
        }

        demuxer.append(data, timeOffset, contiguous, accurateTimeOffset);
      }
    }

    export default DemuxerInline;