从事件链角度解析video-dev/hls.js库
src/hls.js文件
1、new Hls()语句执行过程没有监听器执行;
2、涉及三个入口事件触发,分别是manifest_loading、media_attaching和destroying;
3、暴露的两个主要API:loadSource()用于加载.m3u8文件路径;attachMedia()挂载media元素。
xxx-controller.js和xxx-loader.js两类文件执行过程
基本原理:
首先有一个入口事件,比如是hls源文件中触发的manifest_loading,因此执行该 controller和loader文件 中对应的事件处理函数(或称监听器,以on开头的函数),
该函数内部可能又有新的事件触发,执行该函数新的监听器。
文件分析:
每个文件通过构造函数注册事件监听器,监听器函数以onXXXX命名(这个由src/event-handler.js的处理逻辑完成),
监听器内部可能有新的事件触发,如有,通过hls.trigger()函数表示,该函数第一个参数是触发的事件类型,事件类型在src/event.js文件里面定义。
这个新触发的函数的监听器有可能就在该文件内部,也有可能在另外一个文件。
举个例子,src/hls.js->loadSource()函数内部触发Event.MANIFEST_LOADING事件,通过表1可知,playlist-loader.js的构造函数
内部注册了Event.MANIFEST_LOADING事件的监听器,所以会调用playlist-loader.js内部的onManifestLoading()函数,而onManifestLoading()函数通过调用load()继而调用loadsuccess()
触发了Event.MANIFEST_LOADED事件,通过熟悉源代码,我们知道,audio-track-controller.js的构造函数里注册了
Event.MANIFEST_LOADED事件的监听器onManifestLoaded(),因此该监听器执行,该监听器内部又触发了Event.AUDIO_TRACKS_UPDATED事件,
而通过audio-track-controller.js构造函数中注册的监听器列表我们知道,audio-track-controller.js文件没有注册Event.AUDIO_TRACKS_UPDATED事件的监听器,
通过在dist/hls.js中查找,发现Event.AUDIO_TRACKS_UPDATED事件的监听器定义在audio-stream-controller.js文件中。
不过因我们没有在audio-stream-controller.js中找到onAudioTracksUpdated()监听器,因此这条事件触发链到此中断。
src/hls.js的三个入口事件
manifest_loading、media_attaching和destroying,前两个重要,起着将几乎全部事件(大约53个)串联起来的作用。
有五个文件注册了manifest_loading事件的监听器,4个文件注册了media_attaching事件的监听器。见下表。
manifest_loading事件(表1)
类型 |
文件位置 |
描述 |
事件定义 |
src/event.js |
事件触发 |
src/hls.js->loadsource函数 |
入口事件 |
事件监听器 |
playlist-loader.js构造函数 |
|
stream-loader.js构造函数 |
|
audio-track-controller.js构造函数 |
|
timeline-controller.js构造函数 |
与media_attaching事件触发后涉及的文件相同 |
|
subtitle-track-controller.js构造函数 |
media_attaching事件(表2)
类型 |
文件位置 |
描述 |
事件定义 |
src/event.js |
事件触发 |
src/hls.js->attachmedia函数 |
入口事件 |
事件监听器 |
buffer-controller.js构造函数 |
|
cap-level-controller.js构造函数 |
|
fps-controller.js构造函数 |
|
timeline-controller.js构造函数 |
与manifest_loading事件触发后涉及的文件相同 |
事件监听、触发 与 文件、函数 映射表
以下表格描述了每个loader类或controller类文件中涉及的事件的监听器列表和触发列表,并列出了
调用监听器(触发事件)的函数名称。
表3.1-3.5是注册有manifest-loading事件监听器的文件
表3.6-3.9是注册有media_attaching事件监听器的文件
表格中,触发事件列表一列中有(2)或(3)的,表示触发的次数。
playlist-loader.js文件(表3.1)
监听器列表 |
触发事件列表 |
触发源函数 |
Event.MANIFEST_LOADING |
manifest_loaded |
|
Event.LEVEL_LOADING |
level_loaded |
|
Event.AUDIO_TRACK_LOADING |
audio_track_loaded |
|
Event.SUBTITLE_TRACK_LOADING |
subtitle_track_loaded |
|
|
error |
|
stream-controller.js文件(表3.2)
序号 |
监听器列表 |
触发事件列表 |
触发源函数 |
1 |
Event.MEDIA_ATTACHED |
buffer_eos |
|
2 |
Event.MEDIA_DETACHING |
key_loading |
|
3 |
Event.MANIFEST_LOADING |
error |
|
4 |
Event.MANIFEST_PARSED |
frag_loading |
|
5 |
Event.LEVEL_LOADED |
stream_state_transition |
|
6 |
Event.KEY_LOADED |
frag_changed |
|
7 |
Event.FRAG_LOADED |
level_switched |
|
8 |
Event.FRAG_LOAD_EMERGENCY_ABORTED |
buffer_flushing(2) |
|
9 |
Event.FRAG_PARSING_INIT_SEGMENT |
buffer_reset |
|
10 |
Event.FRAG_PARSING_DATA |
level_updated |
|
11 |
Event.FRAG_PARSED |
frag_buffered(3) |
|
12 |
Event.ERROR |
buffer_codecs |
|
13 |
Event.AUDIO_TRACK_SWITCHING |
buffer_appending(2) |
|
14 |
Event.AUDIO_TRACK_SWITCHED |
level_pts_updated |
|
15 |
Event.BUFFER_CREATED |
audio_track_switched |
|
16 |
Event.BUFFER_APPENDED |
|
|
17 |
Event.BUFFER_FLUSHED |
|
|
audio-track-controller.js文件(表3.3)
监听器列表 |
触发事件列表 |
触发源函数 |
Event.MANIFEST_LOADING |
audio_tracks_updated |
|
Event.MANIFEST_LOADED |
audio_track_switch |
|
Event.AUDIO_TRACK_LOADED |
audio_track_switching |
|
Event.ERROR |
audio_track_loading |
|
subtitle-track-controller.js文件(表3.4)
监听器列表 |
触发事件列表 |
触发源函数 |
Event.MEDIA_ATTACHED |
subtitle_tracks_updated |
|
Event.MEDIA_DETACHING |
subtitle_track_loading |
|
Event.MANIFEST_LOADING |
subtitle_track_switch |
|
Event.MANIFEST_LOADED |
|
|
Event.SUBTITLE_TRACK_LOADED |
|
|
timeline-controller.js文件(表3.5)
监听器列表 |
触发事件列表 |
触发源函数 |
Event.MEDIA_ATTACHING |
subtitle_frag_processed |
|
Event.MEDIA_DETACHING |
|
|
Event.FRAG_PARSING_USERDATA |
|
|
Event.MANIFEST_LOADING |
|
|
Event.MANIFEST_LOADED |
|
|
Event.FRAG_LOADED |
|
|
Event.LEVEL_SWITCHING |
|
|
Event.INIT_PTS_FOUND |
|
|
buffer-controller.js文件(表3.6)
监听器列表 |
触发事件列表 |
触发源函数 |
Event.MEDIA_ATTACHING |
media_detached |
|
Event.MEDIA_DETACHING |
media_attached |
|
Event.MANIFEST_PARSED |
buffer_appended |
|
Event.BUFFER_RESET |
error |
|
Event.BUFFER_APPENDING |
buffer_created |
|
Event.BUFFER_CODECS |
buffer_flushed |
|
Event.BUFFER_EOS |
|
|
Event.BUFFER_FLUSHING |
|
|
Event.LEVEL_PTS_UPDATED |
|
|
Event.LEVEL_UPDATED |
|
|
cap-level-controller.js文件(表3.7)
监听器列表 |
触发事件列表 |
触发源函数 |
Event.FPS_DROP_LEVEL_CAPPING |
|
|
Event.MEDIA_ATTACHING |
|
|
Event.MANIFEST_PARSED |
|
|
fps-controller.js文件(表3.8)
监听器列表 |
触发事件列表 |
触发源函数 |
Event.MEDIA_ATTACHING |
fps_drop |
|
|
fps_drop_frag_processed |
|
timeline-controller.js文件(表3.9)
见表3.5