@startuml

participant SegmentLoader order 1
participant "media-segment-request" order 2
participant XMLHttpRequest order 3
participant "segment-transmuxer" order 4
participant mux.js order 5

SegmentLoader -> "media-segment-request" : mediaSegmentRequest(...)
"media-segment-request" -> XMLHttpRequest : request for segment/key/init segment

group Request
  XMLHttpRequest -> "media-segment-request" : //segment progress//
  note over "media-segment-request" #moccasin
   If handling partial data,
   tries to transmux new
   segment bytes.
  end note
  "media-segment-request" -> SegmentLoader : progressFn(...)
  note left
    Forwards "progress" events from
    the XML HTTP Request.
  end note
  group Transmux
    "media-segment-request" -> "segment-transmuxer" : transmux(...)

    "segment-transmuxer" -> mux.js : postMessage(...setAudioAppendStart...)
    note left
      Used for checking for overlap when
      prefixing audio with silence.
    end note
    "segment-transmuxer" -> mux.js : postMessage(...alignGopsWith...)
    note left
      Used for aligning gops when overlapping
      content (switching renditions) to fix
      some browser glitching.
    end note

    "segment-transmuxer" -> mux.js : postMessage(...push...)
    note left
      Pushes bytes into the transmuxer pipeline.
    end note

    "segment-transmuxer" -> mux.js : postMessage(...partialFlush...)
    note left #moccasin
      Collates any complete frame data
      from partial segment and
      caches remainder.
    end note
    "segment-transmuxer" -> mux.js : postMessage(...flush...)
    note left
      Collates any complete frame data
      from segment, caches only data
      required between segments.
    end note

    "mux.js" -> "segment-transmuxer" : postMessage(...trackinfo...)
    "segment-transmuxer" -> "media-segment-request" : onTrackInfo(...)
    "media-segment-request" -> SegmentLoader : trackInfoFn(...)
    note left
      Gets whether the segment
      has audio and/or video.
    end note
    "mux.js" -> "segment-transmuxer" : postMessage(...audioTimingInfo...)
    "segment-transmuxer" -> "media-segment-request" : onAudioTimingInfo(...)
    "mux.js" -> "segment-transmuxer" : postMessage(...videoTimingInfo...)
    "segment-transmuxer" -> "media-segment-request" : onVideoTimingInfo(...)
    "media-segment-request" -> SegmentLoader : timingInfoFn(...)
    note left
      Gets the audio/video
      start/end times.
    end note

    "mux.js" -> "segment-transmuxer" : postMessage(...caption...)
    "segment-transmuxer" -> "media-segment-request" : onCaptions(...)
    "media-segment-request" -> SegmentLoader : captionsFn(...)
    note left
      Gets captions from transmux.
    end note

    "mux.js" -> "segment-transmuxer" : postMessage(...id3Frame...)
    "segment-transmuxer" -> "media-segment-request" : onId3(...)
    "media-segment-request" -> SegmentLoader : id3Fn(...)
    note left
      Gets metadata from transmux.
    end note

    "mux.js" -> "segment-transmuxer" : postMessage(...data...)
    "segment-transmuxer" -> "media-segment-request" : onData(...)
    "media-segment-request" -> SegmentLoader : dataFn(...)
    note left
      Gets an fmp4 segment
      ready to be appended.
    end note

    "mux.js" -> "segment-transmuxer" : postMessage(...done...)
    note left
      Gathers GOP info, and calls
      done callback.
    end note
    "segment-transmuxer" -> "media-segment-request" : onDone(...)
    "media-segment-request" -> SegmentLoader : doneFn(...)
    note left
      Queues callbacks on source
      buffer queue to wait for
      appends to complete.
    end note
  end
  XMLHttpRequest -> "media-segment-request" : //segment request finished//
end

SegmentLoader -> SegmentLoader : handleAppendsDone_()
note left
  Saves segment timing info
  and starts next request.
end note

@enduml
