index-light.html 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8" />
  5. <title>hls.js demo</title>
  6. <link
  7. rel="stylesheet"
  8. href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css"
  9. />
  10. <link
  11. rel="stylesheet"
  12. href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap-theme.min.css"
  13. />
  14. <link rel="stylesheet" href="style.css" />
  15. <script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script>
  16. <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
  17. <script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.8/FileSaver.min.js"></script>
  18. <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.13.1/ace.js"></script>
  19. </head>
  20. <body>
  21. <div class="header-container">
  22. <header class="wrapper clearfix">
  23. <h1>
  24. <a target="_blank" href="https://github.com/video-dev/hls.js">
  25. <img
  26. src="https://cloud.githubusercontent.com/assets/616833/19739063/e10be95a-9bb9-11e6-8100-2896f8500138.png"
  27. />
  28. </a>
  29. </h1>
  30. <h2 class="title">light demo</h2>
  31. <h3>
  32. <a href="../api-docs">API docs | usage guide</a>
  33. </h3>
  34. </header>
  35. </div>
  36. <div class="main-container">
  37. <header>
  38. <p>
  39. Test your HLS streams in all supported browsers
  40. (Chrome/Firefox/IE11/Edge/Safari).
  41. </p>
  42. <p>Advanced controls are available at the bottom of this page.</p>
  43. <p>
  44. <b
  45. >This page uses hls.light.js. It does not support EME, subs or
  46. alt-audio. Looking for the <i>complete hls.js</i> demo? Go
  47. <a href=".">here</a>.</b
  48. ><br />
  49. </p>
  50. </header>
  51. <div id="controls">
  52. <div class="demo-controls-wrapper">
  53. <select id="streamSelect" class="innerControls">
  54. <option value="" selected>
  55. Select a test-stream from drop-down menu. Or enter custom URL
  56. below
  57. </option>
  58. </select>
  59. <input id="streamURL" class="innerControls" type="text" value="" />
  60. <label
  61. class="innerControls"
  62. title="Uncheck this to disable loading of streams selected from the drop-down above."
  63. >
  64. Enable streaming:
  65. <input id="enableStreaming" type="checkbox" checked />
  66. </label>
  67. <label
  68. class="innerControls"
  69. title="When a media error occurs, attempt to recover playback by calling `hls.recoverMediaError()`."
  70. >
  71. Auto-recover media-errors:
  72. <input id="autoRecoverError" type="checkbox" checked />
  73. </label>
  74. <label
  75. class="innerControls"
  76. title="Stop loading and playback if playback under-buffer stalls. This can help debug stall errors."
  77. >
  78. Stop on first stall:
  79. <input id="stopOnStall" type="checkbox" unchecked />
  80. </label>
  81. <label class="innerControls">
  82. Dump transmuxed fMP4 data:
  83. <input id="dumpfMP4" type="checkbox" unchecked />
  84. </label>
  85. <label class="innerControls">
  86. Metrics history (max limit, -1 is unlimited):
  87. <input id="limitMetrics" style="width: 8em" type="number" />
  88. </label>
  89. <label class="innerControls">
  90. HTML video element width:
  91. <select id="videoSize" style="float: right">
  92. <option value="240px">240px</option>
  93. <option value="426px">426px</option>
  94. <option value="640px">640px</option>
  95. <option value="720px">720px</option>
  96. <option value="854px">854px</option>
  97. <option value="1280px">1280px</option>
  98. <option value="1920px">1920px</option>
  99. <option value="80%">Responsive (80%)</option>
  100. <option value="100%">Responsive (100%)</option>
  101. </select>
  102. </label>
  103. <label class="innerControls">
  104. Current player size:
  105. <span id="currentSize"></span>
  106. </label>
  107. <label class="innerControls">
  108. Current video resolution:
  109. <span id="currentResolution"></span>
  110. </label>
  111. <label class="innerControls permalink">
  112. Permalink:&nbsp;&nbsp;<span id="StreamPermalink"></span>
  113. </label>
  114. </div>
  115. <div class="config-editor-wrapper">
  116. <div class="config-editor-container">
  117. <div id="config-editor">Loading...</div>
  118. </div>
  119. <div class="config-editor-commands">
  120. <label for="config-persistence">
  121. Persist
  122. <input
  123. name="config-persistence"
  124. id="config-persistence"
  125. type="checkbox"
  126. />
  127. </label>
  128. <button name="config-apply" onclick="applyConfigEditorValue()">
  129. Apply
  130. </button>
  131. </div>
  132. </div>
  133. </div>
  134. <video
  135. id="video"
  136. controls
  137. autoplay
  138. class="videoCentered"
  139. style="width: 80%"
  140. ></video>
  141. <br />
  142. <canvas
  143. id="bufferedCanvas"
  144. width="720"
  145. height="15"
  146. class="videoCentered"
  147. onclick="onClickBufferedRange(event);"
  148. style="height: fit-content"
  149. ></canvas>
  150. <br />
  151. <br />
  152. <label class="center">Status:</label>
  153. <pre id="statusOut" class="center" style="white-space: pre-wrap"></pre>
  154. <label class="center">Error:</label>
  155. <pre id="errorOut" class="center" style="white-space: pre-wrap"></pre>
  156. <div
  157. class="center"
  158. style="text-align: center; display: none"
  159. id="toggleButtons"
  160. >
  161. <button
  162. type="button"
  163. class="btn btn-sm demo-tab-btn"
  164. data-tab="playbackControlTab"
  165. onclick="toggleTabClick(this);"
  166. >
  167. Playback
  168. </button>
  169. <button
  170. type="button"
  171. class="btn btn-sm demo-tab-btn"
  172. data-tab="timelineTab"
  173. onclick="toggleTabClick(this);"
  174. >
  175. Timeline
  176. </button>
  177. <button
  178. type="button"
  179. class="btn btn-sm demo-tab-btn"
  180. data-tab="qualityLevelControlTab"
  181. onclick="toggleTabClick(this);"
  182. >
  183. Quality-levels
  184. </button>
  185. <button
  186. type="button"
  187. class="btn btn-sm demo-tab-btn"
  188. data-tab="audioTrackControlTab"
  189. onclick="toggleTabClick(this);"
  190. >
  191. Audio-tracks
  192. </button>
  193. <button
  194. type="button"
  195. class="btn btn-sm demo-tab-btn"
  196. data-tab="metricsDisplayTab"
  197. onclick="toggleTabClick(this); showMetrics();"
  198. >
  199. Real-time metrics
  200. </button>
  201. <button
  202. type="button"
  203. class="btn btn-sm demo-tab-btn"
  204. data-tab="statsDisplayTab"
  205. onclick="toggleTabClick(this);"
  206. >
  207. Buffer &amp; Statistics
  208. </button>
  209. </div>
  210. <div
  211. class="center demo-tab"
  212. id="playbackControlTab"
  213. style="display: none"
  214. >
  215. <br />
  216. <center>
  217. <p>
  218. <span>
  219. <button
  220. type="button"
  221. class="btn btn-sm btn-info"
  222. title="video.play()"
  223. onclick="$('#video')[0].play()"
  224. >
  225. Play
  226. </button>
  227. <button
  228. type="button"
  229. class="btn btn-sm btn-info"
  230. title="video.pause()"
  231. onclick="$('#video')[0].pause()"
  232. >
  233. Pause
  234. </button>
  235. </span>
  236. <span>
  237. <button
  238. type="button"
  239. class="btn btn-sm btn-info"
  240. title="video.playbackRate = text input"
  241. onclick="$('#video')[0].defaultPlaybackRate=$('#video')[0].playbackRate=$('#playback_rate').val();"
  242. >
  243. Playback rate
  244. </button>
  245. <input
  246. type="number"
  247. value="1"
  248. id="playback_rate"
  249. size="8"
  250. style="width: 3em"
  251. onkeydown="if(window.event.keyCode=='13'){$('#video')[0].defaultPlaybackRate=$('#video')[0].playbackRate=$('#playback_rate').val();}"
  252. />
  253. </span>
  254. <span>
  255. <button
  256. type="button"
  257. class="btn btn-sm btn-info"
  258. title="video.currentTime -= 10"
  259. onclick="$('#video')[0].currentTime-=10"
  260. >
  261. - 10 s
  262. </button>
  263. <button
  264. type="button"
  265. class="btn btn-sm btn-info"
  266. title="video.currentTime += 10"
  267. onclick="$('#video')[0].currentTime+=10"
  268. >
  269. + 10 s
  270. </button>
  271. </span>
  272. <span>
  273. <button
  274. type="button"
  275. class="btn btn-sm btn-info"
  276. title="video.currentTime = text input"
  277. onclick="$('#video')[0].currentTime=$('#seek_pos').val();"
  278. >
  279. Seek to
  280. </button>
  281. <input
  282. type="number"
  283. id="seek_pos"
  284. size="8"
  285. style="width: 7em"
  286. onkeydown="if(window.event.keyCode=='13'){$('#video')[0].currentTime=$('#seek_pos').val();}"
  287. />
  288. </span>
  289. </p>
  290. <p>
  291. <span>
  292. <button
  293. type="button"
  294. class="btn btn-xs btn-warning"
  295. title="hls.startLoad()"
  296. onclick="hls.startLoad()"
  297. >
  298. Start loading
  299. </button>
  300. <button
  301. type="button"
  302. class="btn btn-xs btn-warning"
  303. title="hls.stopLoad()"
  304. onclick="hls.stopLoad()"
  305. >
  306. Stop loading
  307. </button>
  308. </span>
  309. <span>
  310. <button
  311. type="button"
  312. class="btn btn-xs btn-warning"
  313. title="hls.attachMedia(video)"
  314. onclick="hls.attachMedia($('#video')[0])"
  315. >
  316. Attach media
  317. </button>
  318. <button
  319. type="button"
  320. class="btn btn-xs btn-warning"
  321. title="hls.detachMedia()"
  322. onclick="hls.detachMedia()"
  323. >
  324. Detach media
  325. </button>
  326. </span>
  327. </p>
  328. <p>
  329. <span>
  330. <button
  331. type="button"
  332. class="btn btn-xs btn-warning"
  333. title="hls.recoverMediaError()"
  334. onclick="hls.recoverMediaError()"
  335. >
  336. Recover media-error
  337. </button>
  338. <button
  339. type="button"
  340. class="btn btn-xs btn-warning"
  341. title="hls.swapAudioCodec()"
  342. onclick="hls.swapAudioCodec()"
  343. >
  344. Swap audio codec
  345. </button>
  346. </span>
  347. </p>
  348. <p>
  349. <span>
  350. <button
  351. type="button"
  352. class="btn btn-xs btn-default"
  353. onclick="$('#streamSelect')[0].selectedIndex++;$('#streamSelect').change()"
  354. >
  355. Next video
  356. </button>
  357. <button
  358. type="button"
  359. class="btn btn-xs btn-default btn-dump"
  360. title="Save dumped audio mp4 appends"
  361. onclick="createfMP4('audio');"
  362. >
  363. Create audio-fmp4
  364. </button>
  365. <button
  366. type="button"
  367. class="btn btn-xs btn-default btn-dump"
  368. title="Save dumped video mp4 appends"
  369. onclick="createfMP4('video')"
  370. >
  371. Create video-fmp4
  372. </button>
  373. </span>
  374. </p>
  375. </center>
  376. </div>
  377. <div
  378. class="center demo-tab demo-timeline-chart-container"
  379. id="timelineTab"
  380. style="display: none"
  381. >
  382. <canvas id="timeline-chart"></canvas>
  383. </div>
  384. <div
  385. class="center demo-tab"
  386. id="qualityLevelControlTab"
  387. style="display: none"
  388. >
  389. <center>
  390. <table>
  391. <tr>
  392. <td>
  393. <p>Currently played level:</p>
  394. </td>
  395. <td>
  396. <div id="currentLevelControl" style="display: inline"></div>
  397. </td>
  398. </tr>
  399. <tr>
  400. <td>
  401. <p>Next level loaded:</p>
  402. </td>
  403. <td>
  404. <div id="nextLevelControl" style="display: inline"></div>
  405. </td>
  406. </tr>
  407. <tr>
  408. <td>
  409. <p>Currently loaded level:</p>
  410. </td>
  411. <td>
  412. <div id="loadLevelControl" style="display: inline"></div>
  413. </td>
  414. </tr>
  415. <tr>
  416. <td>
  417. <p>Cap-limit level (maximum):</p>
  418. </td>
  419. <td>
  420. <div id="levelCappingControl" style="display: inline"></div>
  421. </td>
  422. </tr>
  423. </table>
  424. </center>
  425. </div>
  426. <div
  427. class="center demo-tab"
  428. id="audioTrackControlTab"
  429. style="display: none"
  430. >
  431. <table>
  432. <tr>
  433. <td>Current audio-track:</td>
  434. <td><div id="audioTrackControl" style="display: inline"></div></td>
  435. </tr>
  436. <tr>
  437. <td>Language / Name:</td>
  438. <td>
  439. <div id="audioTrackLabel" style="display: inline">
  440. None selected
  441. </div>
  442. </td>
  443. </tr>
  444. </table>
  445. </div>
  446. <div class="center demo-tab" id="metricsDisplayTab" style="display: none">
  447. <br />
  448. <div id="metricsButton">
  449. <button
  450. type="button"
  451. class="btn btn-xs btn-info"
  452. onclick="$('#metricsButtonWindow').toggle();$('#metricsButtonFixed').toggle();windowSliding=!windowSliding; refreshCanvas()"
  453. >
  454. toggle sliding/fixed window</button
  455. ><br />
  456. <div id="metricsButtonWindow">
  457. <button
  458. type="button"
  459. class="btn btn-xs btn-info"
  460. onclick="timeRangeSetSliding(0)"
  461. >
  462. window ALL
  463. </button>
  464. <button
  465. type="button"
  466. class="btn btn-xs btn-info"
  467. onclick="timeRangeSetSliding(2000)"
  468. >
  469. 2s
  470. </button>
  471. <button
  472. type="button"
  473. class="btn btn-xs btn-info"
  474. onclick="timeRangeSetSliding(5000)"
  475. >
  476. 5s
  477. </button>
  478. <button
  479. type="button"
  480. class="btn btn-xs btn-info"
  481. onclick="timeRangeSetSliding(10000)"
  482. >
  483. 10s
  484. </button>
  485. <button
  486. type="button"
  487. class="btn btn-xs btn-info"
  488. onclick="timeRangeSetSliding(20000)"
  489. >
  490. 20s
  491. </button>
  492. <button
  493. type="button"
  494. class="btn btn-xs btn-info"
  495. onclick="timeRangeSetSliding(30000)"
  496. >
  497. 30s
  498. </button>
  499. <button
  500. type="button"
  501. class="btn btn-xs btn-info"
  502. onclick="timeRangeSetSliding(60000)"
  503. >
  504. 60s
  505. </button>
  506. <button
  507. type="button"
  508. class="btn btn-xs btn-info"
  509. onclick="timeRangeSetSliding(120000)"
  510. >
  511. 120s</button
  512. ><br />
  513. <button
  514. type="button"
  515. class="btn btn-xs btn-info"
  516. onclick="timeRangeZoomIn()"
  517. >
  518. Window Zoom In
  519. </button>
  520. <button
  521. type="button"
  522. class="btn btn-xs btn-info"
  523. onclick="timeRangeZoomOut()"
  524. >
  525. Window Zoom Out</button
  526. ><br />
  527. <button
  528. type="button"
  529. class="btn btn-xs btn-info"
  530. onclick="timeRangeSlideLeft()"
  531. >
  532. <<< Window Slide
  533. </button>
  534. <button
  535. type="button"
  536. class="btn btn-xs btn-info"
  537. onclick="timeRangeSlideRight()"
  538. >
  539. Window Slide >>></button
  540. ><br />
  541. </div>
  542. <div id="metricsButtonFixed">
  543. <button
  544. type="button"
  545. class="btn btn-xs btn-info"
  546. onclick="windowStart=$('#windowStart').val()"
  547. >
  548. fixed window start(ms)
  549. </button>
  550. <input
  551. type="text"
  552. id="windowStart"
  553. defaultValue="0"
  554. size="8"
  555. onkeydown="if(window.event.keyCode=='13'){windowStart=$('#windowStart').val();}"
  556. />
  557. <button
  558. type="button"
  559. class="btn btn-xs btn-info"
  560. onclick="windowEnd=$('#windowEnd').val()"
  561. >
  562. fixed window end(ms)
  563. </button>
  564. <input
  565. type="text"
  566. id="windowEnd"
  567. defaultValue="10000"
  568. size="8"
  569. onkeydown="if(window.event.keyCode=='13'){windowEnd=$('#windowEnd').val();}"
  570. /><br />
  571. </div>
  572. <button
  573. type="button"
  574. class="btn btn-xs btn-success"
  575. onclick="goToMetrics()"
  576. style="font-size: 18px"
  577. >
  578. metrics link
  579. </button>
  580. <button
  581. type="button"
  582. class="btn btn-xs btn-success"
  583. onclick="goToMetricsPermaLink()"
  584. style="font-size: 18px"
  585. >
  586. metrics permalink
  587. </button>
  588. <button
  589. type="button"
  590. class="btn btn-xs btn-success"
  591. onclick="copyMetricsToClipBoard()"
  592. style="font-size: 18px"
  593. >
  594. copy metrics to clipboard
  595. </button>
  596. <canvas
  597. id="bufferTimerange_c"
  598. width="640"
  599. height="100"
  600. style="border: 1px solid #000000"
  601. onmousedown="timeRangeCanvasonMouseDown(event)"
  602. onmousemove="timeRangeCanvasonMouseMove(event)"
  603. onmouseup="timeRangeCanvasonMouseUp(event)"
  604. onmouseout="timeRangeCanvasonMouseOut(event);"
  605. ></canvas>
  606. <canvas
  607. id="bitrateTimerange_c"
  608. width="640"
  609. height="100"
  610. style="border: 1px solid #000000"
  611. ></canvas>
  612. <canvas
  613. id="bufferWindow_c"
  614. width="640"
  615. height="100"
  616. style="border: 1px solid #000000"
  617. onmousemove="windowCanvasonMouseMove(event);"
  618. ></canvas>
  619. <canvas
  620. id="videoEvent_c"
  621. width="640"
  622. height="15"
  623. style="border: 1px solid #000000"
  624. ></canvas>
  625. <canvas
  626. id="loadEvent_c"
  627. width="640"
  628. height="15"
  629. style="border: 1px solid #000000"
  630. ></canvas
  631. ><br />
  632. </div>
  633. </div>
  634. <div class="center demo-tab" id="statsDisplayTab" style="display: none">
  635. <br />
  636. <label>Buffer state:</label>
  637. <pre id="bufferedOut"></pre>
  638. <label>General stats:</label>
  639. <pre id="statisticsOut"></pre>
  640. </div>
  641. </div>
  642. <footer><br /><br /><br /><br /><br /><br /></footer>
  643. <!-- Demo page required libs -->
  644. <script src="canvas.js"></script>
  645. <script src="metrics.js"></script>
  646. <!-- demo build -->
  647. <script src="hls.light.js"></script>
  648. <script src="hls-demo.js"></script>
  649. </body>
  650. </html>