All files / src/controller id3-track-controller.js

8.82% Statements 3/34
0% Branches 0/19
16.67% Functions 1/6
8.82% Lines 3/34

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                      28x       28x 28x                                                                                                                                                      
/*
 * id3 metadata track controller
*/
 
import Event from '../events';
import EventHandler from '../event-handler';
import ID3 from '../demux/id3';
import { sendAddTrackEvent, clearCurrentCues } from '../utils/texttrack-utils';
 
class ID3TrackController extends EventHandler {
  constructor (hls) {
    super(hls,
      Event.MEDIA_ATTACHED,
      Event.MEDIA_DETACHING,
      Event.FRAG_PARSING_METADATA);
    this.id3Track = undefined;
    this.media = undefined;
  }
 
  destroy () {
    EventHandler.prototype.destroy.call(this);
  }
 
  // Add ID3 metatadata text track.
  onMediaAttached (data) {
    this.media = data.media;
    if (!this.media) {
 
    }
  }
 
  onMediaDetaching () {
    clearCurrentCues(this.id3Track);
    this.id3Track = undefined;
    this.media = undefined;
  }
 
  getID3Track (textTracks) {
    for (let i = 0; i < textTracks.length; i++) {
      let textTrack = textTracks[i];
      if (textTrack.kind === 'metadata' && textTrack.label === 'id3') {
        // send 'addtrack' when reusing the textTrack for metadata,
        // same as what we do for captions
        sendAddTrackEvent(textTrack, this.media);
 
        return textTrack;
      }
    }
    return this.media.addTextTrack('metadata', 'id3');
  }
 
  onFragParsingMetadata (data) {
    const fragment = data.frag;
    const samples = data.samples;
 
    // create track dynamically
    if (!this.id3Track) {
      this.id3Track = this.getID3Track(this.media.textTracks);
      this.id3Track.mode = 'hidden';
    }
 
    // Attempt to recreate Safari functionality by creating
    // WebKitDataCue objects when available and store the decoded
    // ID3 data in the value property of the cue
    let Cue = window.WebKitDataCue || window.VTTCue || window.TextTrackCue;
 
    for (let i = 0; i < samples.length; i++) {
      const frames = ID3.getID3Frames(samples[i].data);
      if (frames) {
        const startTime = samples[i].pts;
        let endTime = i < samples.length - 1 ? samples[i + 1].pts : fragment.endPTS;
 
        // Give a slight bump to the endTime if it's equal to startTime to avoid a SyntaxError in IE
        if (startTime === endTime)
          endTime += 0.0001;
 
        for (let j = 0; j < frames.length; j++) {
          const frame = frames[j];
          // Safari doesn't put the timestamp frame in the TextTrack
          if (!ID3.isTimeStampFrame(frame)) {
            const cue = new Cue(startTime, endTime, '');
            cue.value = frame;
            this.id3Track.addCue(cue);
          }
        }
      }
    }
  }
}
 
export default ID3TrackController;