@opendesign-plus/components 0.0.1-rc.34 → 0.0.1-rc.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-OElCookieNotice.cjs.js +1 -1
- package/dist/chunk-OElCookieNotice.es.js +6 -6
- package/dist/components/activity/index.d.ts +9 -9
- package/dist/components/banner/index.d.ts +6 -6
- package/dist/components/events/index.d.ts +20 -20
- package/dist/components/header/OHeaderMobile.vue.d.ts +22 -22
- package/dist/components/header/components/HeaderNavMobile.vue.d.ts +3 -3
- package/dist/components/header/index.d.ts +27 -27
- package/dist/components/header-search/index.d.ts +13 -13
- package/dist/components/meeting/OMeetingPlayback.vue.d.ts +6 -6
- package/dist/components/meeting/components/OMeetingCalendarSelector.vue.d.ts +664 -0
- package/dist/components/meeting/components/OMeetingPlaybackVideo.vue.d.ts +1 -1
- package/dist/components/meeting/index.d.ts +31 -31
- package/dist/components/search/index.d.ts +11 -11
- package/dist/components.cjs.js +1 -1
- package/dist/components.css +1 -1
- package/dist/components.es.js +139 -131
- package/dist/treeshaking/_virtual/@babel/runtime/helpers/esm/extends.js.mjs +12 -0
- package/dist/treeshaking/_virtual/@babel/runtime/helpers/extends.js.mjs +22 -0
- package/dist/treeshaking/_virtual/@babel/runtime/helpers/extends.js2.mjs +4 -0
- package/dist/treeshaking/_virtual/@videojs/vhs-utils/es/byte-helpers.js.mjs +141 -0
- package/dist/treeshaking/_virtual/@videojs/vhs-utils/es/codecs.js.mjs +158 -0
- package/dist/treeshaking/_virtual/@videojs/vhs-utils/es/containers.js.mjs +161 -0
- package/dist/treeshaking/_virtual/@videojs/vhs-utils/es/decode-b64-to-uint8-array.js.mjs +15 -0
- package/dist/treeshaking/_virtual/@videojs/vhs-utils/es/ebml-helpers.js.mjs +126 -0
- package/dist/treeshaking/_virtual/@videojs/vhs-utils/es/id3-helpers.js.mjs +32 -0
- package/dist/treeshaking/_virtual/@videojs/vhs-utils/es/media-groups.js.mjs +13 -0
- package/dist/treeshaking/_virtual/@videojs/vhs-utils/es/media-types.js.mjs +17 -0
- package/dist/treeshaking/_virtual/@videojs/vhs-utils/es/mp4-helpers.js.mjs +57 -0
- package/dist/treeshaking/_virtual/@videojs/vhs-utils/es/nal-helpers.js.mjs +78 -0
- package/dist/treeshaking/_virtual/@videojs/vhs-utils/es/resolve-url.js.mjs +23 -0
- package/dist/treeshaking/_virtual/@videojs/vhs-utils/es/stream.js.mjs +51 -0
- package/dist/treeshaking/_virtual/@videojs/xhr/lib/http-handler.js.mjs +55 -0
- package/dist/treeshaking/_virtual/@videojs/xhr/lib/index.js.mjs +7 -0
- package/dist/treeshaking/_virtual/@videojs/xhr/lib/index.js2.mjs +300 -0
- package/dist/treeshaking/_virtual/@videojs/xhr/lib/index.js3.mjs +4 -0
- package/dist/treeshaking/_virtual/@videojs/xhr/lib/interceptors.js.mjs +109 -0
- package/dist/treeshaking/_virtual/@videojs/xhr/lib/retry.js.mjs +104 -0
- package/dist/treeshaking/_virtual/@xmldom/xmldom/lib/conventions.js.mjs +142 -0
- package/dist/treeshaking/_virtual/@xmldom/xmldom/lib/conventions.js2.mjs +4 -0
- package/dist/treeshaking/_virtual/@xmldom/xmldom/lib/dom-parser.js.mjs +224 -0
- package/dist/treeshaking/_virtual/@xmldom/xmldom/lib/dom-parser.js2.mjs +4 -0
- package/dist/treeshaking/_virtual/@xmldom/xmldom/lib/dom.js.mjs +1449 -0
- package/dist/treeshaking/_virtual/@xmldom/xmldom/lib/dom.js2.mjs +4 -0
- package/dist/treeshaking/_virtual/@xmldom/xmldom/lib/entities.js.mjs +2149 -0
- package/dist/treeshaking/_virtual/@xmldom/xmldom/lib/entities.js2.mjs +4 -0
- package/dist/treeshaking/_virtual/@xmldom/xmldom/lib/index.js.mjs +5 -0
- package/dist/treeshaking/_virtual/@xmldom/xmldom/lib/index.js2.mjs +16 -0
- package/dist/treeshaking/_virtual/@xmldom/xmldom/lib/index.js3.mjs +4 -0
- package/dist/treeshaking/_virtual/@xmldom/xmldom/lib/sax.js.mjs +594 -0
- package/dist/treeshaking/_virtual/@xmldom/xmldom/lib/sax.js2.mjs +4 -0
- package/dist/treeshaking/_virtual/___vite-browser-external.mjs +6 -0
- package/dist/treeshaking/_virtual/__vite-browser-external.mjs +4 -0
- package/dist/treeshaking/_virtual/_commonjsHelpers.mjs +33 -0
- package/dist/treeshaking/_virtual/_plugin-vue_export-helper.mjs +10 -0
- package/dist/treeshaking/_virtual/global/document.js.mjs +7 -0
- package/dist/treeshaking/_virtual/global/document.js2.mjs +24 -0
- package/dist/treeshaking/_virtual/global/window.js.mjs +7 -0
- package/dist/treeshaking/_virtual/global/window.js2.mjs +22 -0
- package/dist/treeshaking/_virtual/icon-all.mjs +20 -0
- package/dist/treeshaking/_virtual/icon-avatar-line.mjs +21 -0
- package/dist/treeshaking/_virtual/icon-caret-left.mjs +20 -0
- package/dist/treeshaking/_virtual/icon-caret-right.mjs +20 -0
- package/dist/treeshaking/_virtual/icon-checked.mjs +20 -0
- package/dist/treeshaking/_virtual/icon-chevron-down.mjs +20 -0
- package/dist/treeshaking/_virtual/icon-chevron-right.mjs +17 -0
- package/dist/treeshaking/_virtual/icon-chevron-up.mjs +20 -0
- package/dist/treeshaking/_virtual/icon-close.mjs +20 -0
- package/dist/treeshaking/_virtual/icon-competition.mjs +31 -0
- package/dist/treeshaking/_virtual/icon-copy.mjs +21 -0
- package/dist/treeshaking/_virtual/icon-delete-hover.mjs +24 -0
- package/dist/treeshaking/_virtual/icon-delete.mjs +17 -0
- package/dist/treeshaking/_virtual/icon-event.mjs +21 -0
- package/dist/treeshaking/_virtual/icon-events.mjs +31 -0
- package/dist/treeshaking/_virtual/icon-filter.mjs +21 -0
- package/dist/treeshaking/_virtual/icon-header-back.mjs +20 -0
- package/dist/treeshaking/_virtual/icon-header-menu.mjs +20 -0
- package/dist/treeshaking/_virtual/icon-header-search.mjs +26 -0
- package/dist/treeshaking/_virtual/icon-help.mjs +21 -0
- package/dist/treeshaking/_virtual/icon-image-upload.mjs +20 -0
- package/dist/treeshaking/_virtual/icon-image-zoomin.mjs +20 -0
- package/dist/treeshaking/_virtual/icon-locale.mjs +21 -0
- package/dist/treeshaking/_virtual/icon-meet.mjs +21 -0
- package/dist/treeshaking/_virtual/icon-moon.mjs +21 -0
- package/dist/treeshaking/_virtual/icon-playing.mjs +33 -0
- package/dist/treeshaking/_virtual/icon-refresh.mjs +21 -0
- package/dist/treeshaking/_virtual/icon-release.mjs +31 -0
- package/dist/treeshaking/_virtual/icon-search.mjs +17 -0
- package/dist/treeshaking/_virtual/icon-speaker.mjs +17 -0
- package/dist/treeshaking/_virtual/icon-summit.mjs +21 -0
- package/dist/treeshaking/_virtual/icon-summit2.mjs +31 -0
- package/dist/treeshaking/_virtual/icon-sun.mjs +21 -0
- package/dist/treeshaking/_virtual/icon-tip.mjs +21 -0
- package/dist/treeshaking/_virtual/icon-tips.mjs +17 -0
- package/dist/treeshaking/_virtual/is-function/index.js.mjs +20 -0
- package/dist/treeshaking/_virtual/m3u8-parser/dist/m3u8-parser.es.js.mjs +1390 -0
- package/dist/treeshaking/_virtual/mpd-parser/dist/mpd-parser.es.js.mjs +1693 -0
- package/dist/treeshaking/_virtual/mux.js/lib/tools/parse-sidx.js.mjs +7 -0
- package/dist/treeshaking/_virtual/mux.js/lib/tools/parse-sidx.js2.mjs +45 -0
- package/dist/treeshaking/_virtual/mux.js/lib/utils/clock.js.mjs +5 -0
- package/dist/treeshaking/_virtual/mux.js/lib/utils/clock.js2.mjs +42 -0
- package/dist/treeshaking/_virtual/mux.js/lib/utils/numbers.js.mjs +27 -0
- package/dist/treeshaking/_virtual/video.js/dist/video-js.css +2018 -0
- package/dist/treeshaking/_virtual/video.js/dist/video.es.js.mjs +40111 -0
- package/dist/treeshaking/_virtual/videojs-vtt.js/lib/browser-index.js.mjs +7 -0
- package/dist/treeshaking/_virtual/videojs-vtt.js/lib/browser-index.js2.mjs +37 -0
- package/dist/treeshaking/_virtual/videojs-vtt.js/lib/browser-index.js3.mjs +4 -0
- package/dist/treeshaking/_virtual/videojs-vtt.js/lib/vtt.js.mjs +1082 -0
- package/dist/treeshaking/_virtual/videojs-vtt.js/lib/vttcue.js.mjs +235 -0
- package/dist/treeshaking/_virtual/videojs-vtt.js/lib/vttregion.js.mjs +122 -0
- package/dist/treeshaking/assets/meeting/empty.png.mjs +4 -0
- package/dist/treeshaking/assets/meeting/transparent.png.mjs +4 -0
- package/dist/treeshaking/components/activity/OActivityApproval.css +638 -0
- package/dist/treeshaking/components/activity/OActivityApproval.vue.d.ts +273 -0
- package/dist/treeshaking/components/activity/OActivityApproval.vue.mjs +718 -0
- package/dist/treeshaking/components/activity/OActivityApproval.vue4.mjs +6 -0
- package/dist/treeshaking/components/activity/OActivityApproval2.css +331 -0
- package/dist/treeshaking/components/activity/OActivityForm.css +367 -0
- package/dist/treeshaking/components/activity/OActivityForm.vue.d.ts +138 -0
- package/dist/treeshaking/components/activity/OActivityForm.vue.mjs +628 -0
- package/dist/treeshaking/components/activity/OActivityForm.vue4.mjs +6 -0
- package/dist/treeshaking/components/activity/OActivityForm2.css +330 -0
- package/dist/treeshaking/components/activity/OActivityMyCalendar.css +1237 -0
- package/dist/treeshaking/components/activity/OActivityMyCalendar.vue.d.ts +636 -0
- package/dist/treeshaking/components/activity/OActivityMyCalendar.vue.mjs +856 -0
- package/dist/treeshaking/components/activity/OActivityMyCalendar.vue4.mjs +6 -0
- package/dist/treeshaking/components/activity/OActivityMyCalendar2.css +314 -0
- package/dist/treeshaking/components/activity/composables/useActivityConfig.d.ts +17 -0
- package/dist/treeshaking/components/activity/composables/useActivityConfig.mjs +139 -0
- package/dist/treeshaking/components/activity/config.d.ts +1 -0
- package/dist/treeshaking/components/activity/config.mjs +4 -0
- package/dist/treeshaking/components/activity/index.d.ts +648 -0
- package/dist/treeshaking/components/activity/index.mjs +29 -0
- package/dist/treeshaking/components/activity/types.d.ts +88 -0
- package/dist/treeshaking/components/banner/OBanner.css +151 -0
- package/dist/treeshaking/components/banner/OBanner.vue.d.ts +13 -0
- package/dist/treeshaking/components/banner/OBanner.vue.mjs +8 -0
- package/dist/treeshaking/components/banner/OBanner.vue2.mjs +141 -0
- package/dist/treeshaking/components/banner/OBanner2.css +39 -0
- package/dist/treeshaking/components/banner/OBannerContent.css +113 -0
- package/dist/treeshaking/components/banner/OBannerContent.vue.d.ts +7 -0
- package/dist/treeshaking/components/banner/OBannerContent.vue.mjs +7 -0
- package/dist/treeshaking/components/banner/OBannerContent.vue2.mjs +102 -0
- package/dist/treeshaking/components/banner/index.d.ts +68 -0
- package/dist/treeshaking/components/banner/index.mjs +16 -0
- package/dist/treeshaking/components/banner/types.d.ts +31 -0
- package/dist/treeshaking/components/common/AppAvatar.css +20 -0
- package/dist/treeshaking/components/common/AppAvatar.vue.mjs +7 -0
- package/dist/treeshaking/components/common/AppAvatar.vue2.mjs +83 -0
- package/dist/treeshaking/components/common/ClientOnly.vue.mjs +16 -0
- package/dist/treeshaking/components/common/ClientOnly.vue2.mjs +4 -0
- package/dist/treeshaking/components/common/ContentWrapper.css +36 -0
- package/dist/treeshaking/components/common/ContentWrapper.vue.mjs +7 -0
- package/dist/treeshaking/components/common/ContentWrapper.vue2.mjs +50 -0
- package/dist/treeshaking/components/common/MoreText.css +69 -0
- package/dist/treeshaking/components/common/MoreText.vue.mjs +7 -0
- package/dist/treeshaking/components/common/MoreText.vue2.mjs +88 -0
- package/dist/treeshaking/components/common/ThFilter.css +146 -0
- package/dist/treeshaking/components/common/ThFilter.vue.mjs +270 -0
- package/dist/treeshaking/components/common/ThFilter.vue3.mjs +5 -0
- package/dist/treeshaking/components/config-provider/OPlusConfigProvider.vue.d.ts +24 -0
- package/dist/treeshaking/components/config-provider/OPlusConfigProvider.vue.mjs +33 -0
- package/dist/treeshaking/components/config-provider/OPlusConfigProvider.vue2.mjs +4 -0
- package/dist/treeshaking/components/config-provider/index.d.ts +30 -0
- package/dist/treeshaking/components/config-provider/index.mjs +9 -0
- package/dist/treeshaking/components/cookie-notice/OCookieNotice.css +35 -0
- package/dist/treeshaking/components/cookie-notice/OCookieNotice.vue.d.ts +17 -0
- package/dist/treeshaking/components/cookie-notice/OCookieNotice.vue.mjs +8 -0
- package/dist/treeshaking/components/cookie-notice/OCookieNotice.vue2.mjs +367 -0
- package/dist/treeshaking/components/cookie-notice/OCookieNotice2.css +309 -0
- package/dist/treeshaking/components/cookie-notice/index.d.ts +53 -0
- package/dist/treeshaking/components/cookie-notice/index.mjs +9 -0
- package/dist/treeshaking/components/element-plus/OElCookieNotice.css +306 -0
- package/dist/treeshaking/components/element-plus/OElCookieNotice.vue.d.ts +34 -0
- package/dist/treeshaking/components/element-plus/OElCookieNotice.vue.mjs +8 -0
- package/dist/treeshaking/components/element-plus/OElCookieNotice.vue2.mjs +384 -0
- package/dist/treeshaking/components/element-plus/OElCookieNotice2.css +691 -0
- package/dist/treeshaking/components/element-plus/index.d.ts +2 -0
- package/dist/treeshaking/components/events/OEventsApply.css +583 -0
- package/dist/treeshaking/components/events/OEventsApply.vue.d.ts +16 -0
- package/dist/treeshaking/components/events/OEventsApply.vue.mjs +98 -0
- package/dist/treeshaking/components/events/OEventsApply.vue3.mjs +5 -0
- package/dist/treeshaking/components/events/OEventsCalendar.css +501 -0
- package/dist/treeshaking/components/events/OEventsCalendar.vue.d.ts +5 -0
- package/dist/treeshaking/components/events/OEventsCalendar.vue.mjs +289 -0
- package/dist/treeshaking/components/events/OEventsCalendar.vue3.mjs +5 -0
- package/dist/treeshaking/components/events/OEventsList.css +470 -0
- package/dist/treeshaking/components/events/OEventsList.vue.d.ts +26 -0
- package/dist/treeshaking/components/events/OEventsList.vue.mjs +237 -0
- package/dist/treeshaking/components/events/OEventsList.vue3.mjs +5 -0
- package/dist/treeshaking/components/events/config.d.ts +14 -0
- package/dist/treeshaking/components/events/config.mjs +37 -0
- package/dist/treeshaking/components/events/index.d.ts +78 -0
- package/dist/treeshaking/components/events/index.mjs +26 -0
- package/dist/treeshaking/components/events/types.d.ts +73 -0
- package/dist/treeshaking/components/events/types.mjs +9 -0
- package/{src/components/events/utils.ts → dist/treeshaking/components/events/utils.d.ts} +7 -9
- package/dist/treeshaking/components/events/utils.mjs +6 -0
- package/dist/treeshaking/components/footer/OFooter.css +617 -0
- package/dist/treeshaking/components/footer/OFooter.vue.d.ts +46 -0
- package/dist/treeshaking/components/footer/OFooter.vue.mjs +7 -0
- package/dist/treeshaking/components/footer/OFooter.vue2.mjs +348 -0
- package/dist/treeshaking/components/footer/index.d.ts +89 -0
- package/dist/treeshaking/components/footer/index.mjs +9 -0
- package/dist/treeshaking/components/header/OHeader.css +65 -0
- package/dist/treeshaking/components/header/OHeader.vue.d.ts +30 -0
- package/dist/treeshaking/components/header/OHeader.vue.mjs +7 -0
- package/dist/treeshaking/components/header/OHeader.vue2.mjs +118 -0
- package/dist/treeshaking/components/header/OHeaderMobile.css +106 -0
- package/dist/treeshaking/components/header/OHeaderMobile.vue.d.ts +178 -0
- package/dist/treeshaking/components/header/OHeaderMobile.vue.mjs +7 -0
- package/dist/treeshaking/components/header/OHeaderMobile.vue2.mjs +141 -0
- package/dist/treeshaking/components/header/components/HeaderContent.css +1062 -0
- package/dist/treeshaking/components/header/components/HeaderContent.vue.d.ts +13 -0
- package/dist/treeshaking/components/header/components/HeaderContent.vue.mjs +7 -0
- package/dist/treeshaking/components/header/components/HeaderContent.vue2.mjs +235 -0
- package/dist/treeshaking/components/header/components/HeaderNav.css +141 -0
- package/dist/treeshaking/components/header/components/HeaderNav.vue.d.ts +19 -0
- package/dist/treeshaking/components/header/components/HeaderNav.vue.mjs +7 -0
- package/dist/treeshaking/components/header/components/HeaderNav.vue2.mjs +207 -0
- package/dist/treeshaking/components/header/components/HeaderNavMobile.css +419 -0
- package/dist/treeshaking/components/header/components/HeaderNavMobile.vue.d.ts +36 -0
- package/dist/treeshaking/components/header/components/HeaderNavMobile.vue.mjs +7 -0
- package/dist/treeshaking/components/header/components/HeaderNavMobile.vue2.mjs +229 -0
- package/dist/treeshaking/components/header/index.d.ts +153 -0
- package/dist/treeshaking/components/header/index.mjs +16 -0
- package/dist/treeshaking/components/header/types.d.ts +85 -0
- package/dist/treeshaking/components/header/types.mjs +9 -0
- package/dist/treeshaking/components/header-language-switcher/OHeaderLanguageSwitcher.css +140 -0
- package/dist/treeshaking/components/header-language-switcher/OHeaderLanguageSwitcher.vue.d.ts +58 -0
- package/dist/treeshaking/components/header-language-switcher/OHeaderLanguageSwitcher.vue.mjs +8 -0
- package/dist/treeshaking/components/header-language-switcher/OHeaderLanguageSwitcher.vue2.mjs +125 -0
- package/dist/treeshaking/components/header-language-switcher/OHeaderLanguageSwitcher2.css +11 -0
- package/dist/treeshaking/components/header-language-switcher/index.d.ts +105 -0
- package/dist/treeshaking/components/header-language-switcher/index.mjs +9 -0
- package/dist/treeshaking/components/header-search/OHeaderSearch.css +199 -0
- package/dist/treeshaking/components/header-search/OHeaderSearch.vue.d.ts +1032 -0
- package/dist/treeshaking/components/header-search/OHeaderSearch.vue.mjs +7 -0
- package/dist/treeshaking/components/header-search/OHeaderSearch.vue2.mjs +419 -0
- package/dist/treeshaking/components/header-search/index.d.ts +607 -0
- package/dist/treeshaking/components/header-search/index.mjs +9 -0
- package/dist/treeshaking/components/header-source-code/OHeaderSourceCode.css +133 -0
- package/dist/treeshaking/components/header-source-code/OHeaderSourceCode.vue.d.ts +18 -0
- package/dist/treeshaking/components/header-source-code/OHeaderSourceCode.vue.mjs +7 -0
- package/dist/treeshaking/components/header-source-code/OHeaderSourceCode.vue2.mjs +88 -0
- package/dist/treeshaking/components/header-source-code/index.d.ts +23 -0
- package/dist/treeshaking/components/header-source-code/index.mjs +9 -0
- package/dist/treeshaking/components/header-theme/OHeaderTheme.css +48 -0
- package/dist/treeshaking/components/header-theme/OHeaderTheme.vue.d.ts +25 -0
- package/dist/treeshaking/components/header-theme/OHeaderTheme.vue.mjs +7 -0
- package/dist/treeshaking/components/header-theme/OHeaderTheme.vue2.mjs +86 -0
- package/dist/treeshaking/components/header-theme/index.d.ts +50 -0
- package/dist/treeshaking/components/header-theme/index.mjs +9 -0
- package/dist/treeshaking/components/header-user/OHeaderUser.css +135 -0
- package/dist/treeshaking/components/header-user/OHeaderUser.vue.d.ts +40 -0
- package/dist/treeshaking/components/header-user/OHeaderUser.vue.mjs +8 -0
- package/dist/treeshaking/components/header-user/OHeaderUser.vue2.mjs +121 -0
- package/dist/treeshaking/components/header-user/OHeaderUser2.css +80 -0
- package/dist/treeshaking/components/header-user/index.d.ts +53 -0
- package/dist/treeshaking/components/header-user/index.mjs +9 -0
- package/dist/treeshaking/components/meeting/OMeetingCalendar.css +978 -0
- package/dist/treeshaking/components/meeting/OMeetingCalendar.vue.d.ts +297 -0
- package/dist/treeshaking/components/meeting/OMeetingCalendar.vue.mjs +510 -0
- package/dist/treeshaking/components/meeting/OMeetingCalendar.vue3.mjs +5 -0
- package/dist/treeshaking/components/meeting/OMeetingForm.css +767 -0
- package/dist/treeshaking/components/meeting/OMeetingForm.vue.d.ts +141 -0
- package/dist/treeshaking/components/meeting/OMeetingForm.vue.mjs +1020 -0
- package/dist/treeshaking/components/meeting/OMeetingForm.vue4.mjs +6 -0
- package/dist/treeshaking/components/meeting/OMeetingForm2.css +361 -0
- package/dist/treeshaking/components/meeting/OMeetingMyCalendar.css +1342 -0
- package/dist/treeshaking/components/meeting/OMeetingMyCalendar.vue.d.ts +644 -0
- package/dist/treeshaking/components/meeting/OMeetingMyCalendar.vue.mjs +890 -0
- package/dist/treeshaking/components/meeting/OMeetingMyCalendar.vue4.mjs +6 -0
- package/dist/treeshaking/components/meeting/OMeetingMyCalendar2.css +325 -0
- package/dist/treeshaking/components/meeting/OMeetingPlayback.css +256 -0
- package/dist/treeshaking/components/meeting/OMeetingPlayback.vue.d.ts +94 -0
- package/dist/treeshaking/components/meeting/OMeetingPlayback.vue.mjs +328 -0
- package/dist/treeshaking/components/meeting/OMeetingPlayback.vue3.mjs +5 -0
- package/dist/treeshaking/components/meeting/OMeetingSigCalendar.css +224 -0
- package/dist/treeshaking/components/meeting/OMeetingSigCalendar.vue.d.ts +26 -0
- package/dist/treeshaking/components/meeting/OMeetingSigCalendar.vue.mjs +396 -0
- package/dist/treeshaking/components/meeting/OMeetingSigCalendar.vue3.mjs +5 -0
- package/dist/treeshaking/components/meeting/components/OMeetingCalendarList.css +421 -0
- package/dist/treeshaking/components/meeting/components/OMeetingCalendarList.vue.d.ts +29 -0
- package/dist/treeshaking/components/meeting/components/OMeetingCalendarList.vue.mjs +395 -0
- package/dist/treeshaking/components/meeting/components/OMeetingCalendarList.vue3.mjs +5 -0
- package/dist/treeshaking/components/meeting/components/OMeetingCalendarSelector.css +382 -0
- package/dist/treeshaking/components/meeting/components/OMeetingCalendarSelector.vue.d.ts +664 -0
- package/dist/treeshaking/components/meeting/components/OMeetingCalendarSelector.vue.mjs +132 -0
- package/dist/treeshaking/components/meeting/components/OMeetingCalendarSelector.vue4.mjs +6 -0
- package/dist/treeshaking/components/meeting/components/OMeetingCalendarSelector2.css +346 -0
- package/dist/treeshaking/components/meeting/components/OMeetingDetail.css +113 -0
- package/dist/treeshaking/components/meeting/components/OMeetingDetail.vue.d.ts +13 -0
- package/dist/treeshaking/components/meeting/components/OMeetingDetail.vue.mjs +189 -0
- package/dist/treeshaking/components/meeting/components/OMeetingDetail.vue3.mjs +5 -0
- package/dist/treeshaking/components/meeting/components/OMeetingPlaybackSubtitles.css +564 -0
- package/dist/treeshaking/components/meeting/components/OMeetingPlaybackSubtitles.vue.d.ts +20 -0
- package/dist/treeshaking/components/meeting/components/OMeetingPlaybackSubtitles.vue.mjs +426 -0
- package/dist/treeshaking/components/meeting/components/OMeetingPlaybackSubtitles.vue4.mjs +6 -0
- package/dist/treeshaking/components/meeting/components/OMeetingPlaybackSubtitles2.css +347 -0
- package/dist/treeshaking/components/meeting/components/OMeetingPlaybackVideo.css +431 -0
- package/dist/treeshaking/components/meeting/components/OMeetingPlaybackVideo.vue.d.ts +17 -0
- package/dist/treeshaking/components/meeting/components/OMeetingPlaybackVideo.vue.mjs +244 -0
- package/dist/treeshaking/components/meeting/components/OMeetingPlaybackVideo.vue3.mjs +5 -0
- package/dist/treeshaking/components/meeting/components/OMeetingSigAside.css +171 -0
- package/dist/treeshaking/components/meeting/components/OMeetingSigAside.vue.d.ts +16 -0
- package/dist/treeshaking/components/meeting/components/OMeetingSigAside.vue.mjs +112 -0
- package/dist/treeshaking/components/meeting/components/OMeetingSigAside.vue3.mjs +5 -0
- package/dist/treeshaking/components/meeting/composables/useMeetingConfig.d.ts +14 -0
- package/dist/treeshaking/components/meeting/composables/useMeetingConfig.mjs +97 -0
- package/dist/treeshaking/components/meeting/config.d.ts +12 -0
- package/dist/treeshaking/components/meeting/config.mjs +19 -0
- package/dist/treeshaking/components/meeting/index.d.ts +829 -0
- package/dist/treeshaking/components/meeting/index.mjs +44 -0
- package/dist/treeshaking/components/meeting/types.d.ts +237 -0
- package/dist/treeshaking/components/meeting/types.mjs +17 -0
- package/dist/treeshaking/components/meeting/utils.d.ts +9 -0
- package/dist/treeshaking/components/meeting/utils.mjs +68 -0
- package/dist/treeshaking/components/search/OSearchInput.css +155 -0
- package/dist/treeshaking/components/search/OSearchInput.vue.d.ts +1025 -0
- package/dist/treeshaking/components/search/OSearchInput.vue.mjs +7 -0
- package/dist/treeshaking/components/search/OSearchInput.vue2.mjs +382 -0
- package/dist/treeshaking/components/search/composables/useImageSearch.d.ts +48 -0
- package/dist/treeshaking/components/search/composables/useImageSearch.mjs +134 -0
- package/dist/treeshaking/components/search/composables/useKeywordHighlight.d.ts +2 -0
- package/{src/components/search/composables/useKeywordHighlight.ts → dist/treeshaking/components/search/composables/useKeywordHighlight.mjs} +28 -30
- package/dist/treeshaking/components/search/composables/useSearchHistory.d.ts +14 -0
- package/{src/components/search/composables/useSearchHistory.ts → dist/treeshaking/components/search/composables/useSearchHistory.mjs} +58 -75
- package/dist/treeshaking/components/search/index.d.ts +600 -0
- package/dist/treeshaking/components/search/index.mjs +9 -0
- package/dist/treeshaking/components/search/internal/HighlightText.css +12 -0
- package/dist/treeshaking/components/search/internal/HighlightText.vue.d.ts +9 -0
- package/dist/treeshaking/components/search/internal/HighlightText.vue.mjs +7 -0
- package/dist/treeshaking/components/search/internal/HighlightText.vue2.mjs +33 -0
- package/dist/treeshaking/components/search/internal/SearchImageInput.css +213 -0
- package/dist/treeshaking/components/search/internal/SearchImageInput.vue.d.ts +736 -0
- package/dist/treeshaking/components/search/internal/SearchImageInput.vue.mjs +8 -0
- package/dist/treeshaking/components/search/internal/SearchImageInput.vue2.mjs +305 -0
- package/dist/treeshaking/components/search/internal/SearchImageInput2.css +38 -0
- package/dist/treeshaking/components/search/internal/SearchPanel.css +547 -0
- package/dist/treeshaking/components/search/internal/SearchPanel.vue.d.ts +100 -0
- package/dist/treeshaking/components/search/internal/SearchPanel.vue.mjs +7 -0
- package/dist/treeshaking/components/search/internal/SearchPanel.vue2.mjs +249 -0
- package/{src/components/search/types.ts → dist/treeshaking/components/search/types.d.ts} +20 -25
- package/dist/treeshaking/components/section/OSection.css +173 -0
- package/dist/treeshaking/components/section/OSection.vue.d.ts +37 -0
- package/dist/treeshaking/components/section/OSection.vue.mjs +7 -0
- package/dist/treeshaking/components/section/OSection.vue2.mjs +93 -0
- package/dist/treeshaking/components/section/index.d.ts +47 -0
- package/dist/treeshaking/components/section/index.mjs +9 -0
- package/dist/treeshaking/i18n/en.mjs +281 -0
- package/{src/i18n/index.ts → dist/treeshaking/i18n/index.mjs} +49 -56
- package/dist/treeshaking/i18n/zh.mjs +271 -0
- package/{src/index.ts → dist/treeshaking/index.d.ts} +1 -3
- package/dist/treeshaking/index.mjs +51 -0
- package/dist/treeshaking/shared/provide.mjs +4 -0
- package/package.json +15 -5
- package/docs/design.md +0 -27
- package/docs/design_banner.md +0 -41
- package/docs/design_section.md +0 -27
- package/scripts/generate-components-index.js +0 -62
- package/src/assets/events/svg-icons/icon-checked.svg +0 -3
- package/src/assets/events/svg-icons/icon-competition.svg +0 -7
- package/src/assets/events/svg-icons/icon-events.svg +0 -4
- package/src/assets/events/svg-icons/icon-release.svg +0 -4
- package/src/assets/events/svg-icons/icon-summit.svg +0 -4
- package/src/assets/meeting/empty.png +0 -0
- package/src/assets/meeting/svg-icons/icon-all.svg +0 -4
- package/src/assets/meeting/svg-icons/icon-backward.svg +0 -4
- package/src/assets/meeting/svg-icons/icon-calendar.svg +0 -3
- package/src/assets/meeting/svg-icons/icon-cancel.svg +0 -4
- package/src/assets/meeting/svg-icons/icon-captions.svg +0 -4
- package/src/assets/meeting/svg-icons/icon-close-captions.svg +0 -6
- package/src/assets/meeting/svg-icons/icon-close-fullscreen.svg +0 -6
- package/src/assets/meeting/svg-icons/icon-copy.svg +0 -4
- package/src/assets/meeting/svg-icons/icon-create.svg +0 -5
- package/src/assets/meeting/svg-icons/icon-delete.svg +0 -7
- package/src/assets/meeting/svg-icons/icon-empty.svg +0 -65
- package/src/assets/meeting/svg-icons/icon-event.svg +0 -4
- package/src/assets/meeting/svg-icons/icon-export.svg +0 -3
- package/src/assets/meeting/svg-icons/icon-forward.svg +0 -4
- package/src/assets/meeting/svg-icons/icon-fullscreen.svg +0 -6
- package/src/assets/meeting/svg-icons/icon-help.svg +0 -3
- package/src/assets/meeting/svg-icons/icon-important.svg +0 -4
- package/src/assets/meeting/svg-icons/icon-info.svg +0 -3
- package/src/assets/meeting/svg-icons/icon-meet.svg +0 -4
- package/src/assets/meeting/svg-icons/icon-meeting-message.svg +0 -5
- package/src/assets/meeting/svg-icons/icon-meeting.svg +0 -4
- package/src/assets/meeting/svg-icons/icon-play.svg +0 -5
- package/src/assets/meeting/svg-icons/icon-playing-tip.svg +0 -7
- package/src/assets/meeting/svg-icons/icon-playing.svg +0 -5
- package/src/assets/meeting/svg-icons/icon-question.svg +0 -4
- package/src/assets/meeting/svg-icons/icon-sound.svg +0 -5
- package/src/assets/meeting/svg-icons/icon-speaker.svg +0 -3
- package/src/assets/meeting/svg-icons/icon-summit.svg +0 -4
- package/src/assets/meeting/svg-icons/icon-telligent.svg +0 -3
- package/src/assets/meeting/svg-icons/icon-tip.svg +0 -3
- package/src/assets/meeting/svg-icons/icon-todo.svg +0 -4
- package/src/assets/meeting/transparent.png +0 -0
- package/src/assets/styles/element-plus.scss +0 -277
- package/src/assets/svg-icons/icon-arrow-left.svg +0 -3
- package/src/assets/svg-icons/icon-avatar-line.svg +0 -3
- package/src/assets/svg-icons/icon-caret-left.svg +0 -3
- package/src/assets/svg-icons/icon-caret-right.svg +0 -3
- package/src/assets/svg-icons/icon-chevron-down.svg +0 -3
- package/src/assets/svg-icons/icon-chevron-right.svg +0 -3
- package/src/assets/svg-icons/icon-chevron-up.svg +0 -3
- package/src/assets/svg-icons/icon-close.svg +0 -3
- package/src/assets/svg-icons/icon-delete-hover.svg +0 -4
- package/src/assets/svg-icons/icon-delete.svg +0 -7
- package/src/assets/svg-icons/icon-filter.svg +0 -3
- package/src/assets/svg-icons/icon-header-back.svg +0 -3
- package/src/assets/svg-icons/icon-header-delete.svg +0 -3
- package/src/assets/svg-icons/icon-header-menu.svg +0 -3
- package/src/assets/svg-icons/icon-header-person.svg +0 -3
- package/src/assets/svg-icons/icon-header-search.svg +0 -4
- package/src/assets/svg-icons/icon-image-close.svg +0 -4
- package/src/assets/svg-icons/icon-image-upload.svg +0 -3
- package/src/assets/svg-icons/icon-image-zoomin.svg +0 -3
- package/src/assets/svg-icons/icon-loading.svg +0 -4
- package/src/assets/svg-icons/icon-locale.svg +0 -3
- package/src/assets/svg-icons/icon-log-off.svg +0 -3
- package/src/assets/svg-icons/icon-message.svg +0 -3
- package/src/assets/svg-icons/icon-moon.svg +0 -3
- package/src/assets/svg-icons/icon-outlink.svg +0 -3
- package/src/assets/svg-icons/icon-overview.svg +0 -3
- package/src/assets/svg-icons/icon-refresh.svg +0 -3
- package/src/assets/svg-icons/icon-search.svg +0 -3
- package/src/assets/svg-icons/icon-setting.svg +0 -3
- package/src/assets/svg-icons/icon-sun.svg +0 -3
- package/src/assets/svg-icons/icon-tips.svg +0 -3
- package/src/components/activity/OActivityApproval.vue +0 -868
- package/src/components/activity/OActivityForm.vue +0 -548
- package/src/components/activity/OActivityMyCalendar.vue +0 -1540
- package/src/components/activity/composables/useActivityConfig.ts +0 -141
- package/src/components/activity/config.ts +0 -1
- package/src/components/activity/index.ts +0 -24
- package/src/components/activity/types.ts +0 -95
- package/src/components/banner/OBanner.vue +0 -288
- package/src/components/banner/OBannerContent.vue +0 -175
- package/src/components/banner/index.ts +0 -18
- package/src/components/banner/types.ts +0 -39
- package/src/components/common/AppAvatar.vue +0 -83
- package/src/components/common/ClientOnly.vue +0 -13
- package/src/components/common/ContentWrapper.vue +0 -85
- package/src/components/common/MoreText.vue +0 -124
- package/src/components/common/ThFilter.vue +0 -330
- package/src/components/config-provider/OPlusConfigProvider.vue +0 -32
- package/src/components/config-provider/index.ts +0 -10
- package/src/components/cookie-notice/OCookieNotice.vue +0 -575
- package/src/components/cookie-notice/index.ts +0 -10
- package/src/components/element-plus/OElCookieNotice.vue +0 -603
- package/src/components/element-plus/index.ts +0 -3
- package/src/components/events/OEventsApply.vue +0 -509
- package/src/components/events/OEventsCalendar.vue +0 -600
- package/src/components/events/OEventsList.vue +0 -461
- package/src/components/events/config.ts +0 -35
- package/src/components/events/index.ts +0 -24
- package/src/components/events/types.ts +0 -84
- package/src/components/footer/OFooter.vue +0 -577
- package/src/components/footer/index.ts +0 -10
- package/src/components/header/OHeader.vue +0 -157
- package/src/components/header/OHeaderMobile.vue +0 -184
- package/src/components/header/components/HeaderContent.vue +0 -1125
- package/src/components/header/components/HeaderNav.vue +0 -278
- package/src/components/header/components/HeaderNavMobile.vue +0 -380
- package/src/components/header/index.ts +0 -18
- package/src/components/header/types.ts +0 -96
- package/src/components/header-language-switcher/OHeaderLanguageSwitcher.vue +0 -253
- package/src/components/header-language-switcher/index.ts +0 -10
- package/src/components/header-search/OHeaderSearch.vue +0 -628
- package/src/components/header-search/index.ts +0 -10
- package/src/components/header-source-code/OHeaderSourceCode.vue +0 -151
- package/src/components/header-source-code/index.ts +0 -10
- package/src/components/header-theme/OHeaderTheme.vue +0 -132
- package/src/components/header-theme/index.ts +0 -10
- package/src/components/header-user/OHeaderUser.vue +0 -238
- package/src/components/header-user/index.ts +0 -10
- package/src/components/meeting/OMeetingCalendar.vue +0 -943
- package/src/components/meeting/OMeetingForm.vue +0 -1131
- package/src/components/meeting/OMeetingMyCalendar.vue +0 -1601
- package/src/components/meeting/OMeetingPlayback.vue +0 -469
- package/src/components/meeting/OMeetingSigCalendar.vue +0 -500
- package/src/components/meeting/components/OMeetingCalendarList.vue +0 -626
- package/src/components/meeting/components/OMeetingCalendarSelector.vue +0 -213
- package/src/components/meeting/components/OMeetingDetail.vue +0 -285
- package/src/components/meeting/components/OMeetingPlaybackSubtitles.vue +0 -615
- package/src/components/meeting/components/OMeetingPlaybackVideo.vue +0 -741
- package/src/components/meeting/components/OMeetingSigAside.vue +0 -205
- package/src/components/meeting/composables/useMeetingConfig.ts +0 -108
- package/src/components/meeting/config.ts +0 -48
- package/src/components/meeting/index.ts +0 -45
- package/src/components/meeting/types.ts +0 -270
- package/src/components/meeting/utils.ts +0 -70
- package/src/components/search/OSearchInput.vue +0 -526
- package/src/components/search/composables/useImageSearch.ts +0 -157
- package/src/components/search/index.ts +0 -23
- package/src/components/search/internal/HighlightText.vue +0 -37
- package/src/components/search/internal/SearchImageInput.vue +0 -498
- package/src/components/search/internal/SearchPanel.vue +0 -431
- package/src/components/section/OSection.vue +0 -178
- package/src/components/section/index.ts +0 -10
- package/src/draft/Banner.vue +0 -265
- package/src/draft/ButtonCards.vue +0 -106
- package/src/draft/Feature.vue +0 -134
- package/src/draft/Footer.vue +0 -519
- package/src/draft/HorizontalAnchor.vue +0 -165
- package/src/draft/ItemSwiper.vue +0 -133
- package/src/draft/Logo.vue +0 -141
- package/src/draft/LogoCard.vue +0 -75
- package/src/draft/LogoV2.vue +0 -19
- package/src/draft/MainCard.vue +0 -38
- package/src/draft/MultiCard.vue +0 -95
- package/src/draft/MultiIconCard.vue +0 -74
- package/src/draft/OInfoCard.vue +0 -176
- package/src/draft/Process.vue +0 -81
- package/src/draft/Section.vue +0 -167
- package/src/draft/SingleTabCard.vue +0 -85
- package/src/draft/SliderCard.vue +0 -111
- package/src/env.d.ts +0 -16
- package/src/i18n/en.ts +0 -278
- package/src/i18n/zh.ts +0 -268
- package/src/shared/provide.ts +0 -6
- package/src/shims-vue-dompurify-html.d.ts +0 -17
- package/src/vue.d.ts +0 -10
- package/tsconfig.json +0 -37
- package/vite.config.ts +0 -123
|
@@ -0,0 +1,1693 @@
|
|
|
1
|
+
import resolveUrl from "../../@videojs/vhs-utils/es/resolve-url.js.mjs";
|
|
2
|
+
import window$1 from "../../global/window.js.mjs";
|
|
3
|
+
import { forEachMediaGroup } from "../../@videojs/vhs-utils/es/media-groups.js.mjs";
|
|
4
|
+
import decodeB64ToUint8Array from "../../@videojs/vhs-utils/es/decode-b64-to-uint8-array.js.mjs";
|
|
5
|
+
import { l as libExports } from "../../@xmldom/xmldom/lib/index.js.mjs";
|
|
6
|
+
/*! @name mpd-parser @version 1.3.1 @license Apache-2.0 */
|
|
7
|
+
const isObject = (obj) => {
|
|
8
|
+
return !!obj && typeof obj === "object";
|
|
9
|
+
};
|
|
10
|
+
const merge = (...objects) => {
|
|
11
|
+
return objects.reduce((result, source) => {
|
|
12
|
+
if (typeof source !== "object") {
|
|
13
|
+
return result;
|
|
14
|
+
}
|
|
15
|
+
Object.keys(source).forEach((key) => {
|
|
16
|
+
if (Array.isArray(result[key]) && Array.isArray(source[key])) {
|
|
17
|
+
result[key] = result[key].concat(source[key]);
|
|
18
|
+
} else if (isObject(result[key]) && isObject(source[key])) {
|
|
19
|
+
result[key] = merge(result[key], source[key]);
|
|
20
|
+
} else {
|
|
21
|
+
result[key] = source[key];
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
return result;
|
|
25
|
+
}, {});
|
|
26
|
+
};
|
|
27
|
+
const values = (o) => Object.keys(o).map((k) => o[k]);
|
|
28
|
+
const range = (start, end) => {
|
|
29
|
+
const result = [];
|
|
30
|
+
for (let i = start; i < end; i++) {
|
|
31
|
+
result.push(i);
|
|
32
|
+
}
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
const flatten = (lists) => lists.reduce((x, y) => x.concat(y), []);
|
|
36
|
+
const from = (list) => {
|
|
37
|
+
if (!list.length) {
|
|
38
|
+
return [];
|
|
39
|
+
}
|
|
40
|
+
const result = [];
|
|
41
|
+
for (let i = 0; i < list.length; i++) {
|
|
42
|
+
result.push(list[i]);
|
|
43
|
+
}
|
|
44
|
+
return result;
|
|
45
|
+
};
|
|
46
|
+
const findIndexes = (l, key) => l.reduce((a, e, i) => {
|
|
47
|
+
if (e[key]) {
|
|
48
|
+
a.push(i);
|
|
49
|
+
}
|
|
50
|
+
return a;
|
|
51
|
+
}, []);
|
|
52
|
+
const union = (lists, keyFunction) => {
|
|
53
|
+
return values(lists.reduce((acc, list) => {
|
|
54
|
+
list.forEach((el) => {
|
|
55
|
+
acc[keyFunction(el)] = el;
|
|
56
|
+
});
|
|
57
|
+
return acc;
|
|
58
|
+
}, {}));
|
|
59
|
+
};
|
|
60
|
+
var errors = {
|
|
61
|
+
INVALID_NUMBER_OF_PERIOD: "INVALID_NUMBER_OF_PERIOD",
|
|
62
|
+
DASH_EMPTY_MANIFEST: "DASH_EMPTY_MANIFEST",
|
|
63
|
+
DASH_INVALID_XML: "DASH_INVALID_XML",
|
|
64
|
+
NO_BASE_URL: "NO_BASE_URL",
|
|
65
|
+
SEGMENT_TIME_UNSPECIFIED: "SEGMENT_TIME_UNSPECIFIED",
|
|
66
|
+
UNSUPPORTED_UTC_TIMING_SCHEME: "UNSUPPORTED_UTC_TIMING_SCHEME"
|
|
67
|
+
};
|
|
68
|
+
const urlTypeToSegment = ({
|
|
69
|
+
baseUrl = "",
|
|
70
|
+
source = "",
|
|
71
|
+
range: range2 = "",
|
|
72
|
+
indexRange = ""
|
|
73
|
+
}) => {
|
|
74
|
+
const segment = {
|
|
75
|
+
uri: source,
|
|
76
|
+
resolvedUri: resolveUrl(baseUrl || "", source)
|
|
77
|
+
};
|
|
78
|
+
if (range2 || indexRange) {
|
|
79
|
+
const rangeStr = range2 ? range2 : indexRange;
|
|
80
|
+
const ranges = rangeStr.split("-");
|
|
81
|
+
let startRange = window$1.BigInt ? window$1.BigInt(ranges[0]) : parseInt(ranges[0], 10);
|
|
82
|
+
let endRange = window$1.BigInt ? window$1.BigInt(ranges[1]) : parseInt(ranges[1], 10);
|
|
83
|
+
if (startRange < Number.MAX_SAFE_INTEGER && typeof startRange === "bigint") {
|
|
84
|
+
startRange = Number(startRange);
|
|
85
|
+
}
|
|
86
|
+
if (endRange < Number.MAX_SAFE_INTEGER && typeof endRange === "bigint") {
|
|
87
|
+
endRange = Number(endRange);
|
|
88
|
+
}
|
|
89
|
+
let length;
|
|
90
|
+
if (typeof endRange === "bigint" || typeof startRange === "bigint") {
|
|
91
|
+
length = window$1.BigInt(endRange) - window$1.BigInt(startRange) + window$1.BigInt(1);
|
|
92
|
+
} else {
|
|
93
|
+
length = endRange - startRange + 1;
|
|
94
|
+
}
|
|
95
|
+
if (typeof length === "bigint" && length < Number.MAX_SAFE_INTEGER) {
|
|
96
|
+
length = Number(length);
|
|
97
|
+
}
|
|
98
|
+
segment.byterange = {
|
|
99
|
+
length,
|
|
100
|
+
offset: startRange
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
return segment;
|
|
104
|
+
};
|
|
105
|
+
const byteRangeToString = (byterange) => {
|
|
106
|
+
let endRange;
|
|
107
|
+
if (typeof byterange.offset === "bigint" || typeof byterange.length === "bigint") {
|
|
108
|
+
endRange = window$1.BigInt(byterange.offset) + window$1.BigInt(byterange.length) - window$1.BigInt(1);
|
|
109
|
+
} else {
|
|
110
|
+
endRange = byterange.offset + byterange.length - 1;
|
|
111
|
+
}
|
|
112
|
+
return `${byterange.offset}-${endRange}`;
|
|
113
|
+
};
|
|
114
|
+
const parseEndNumber = (endNumber) => {
|
|
115
|
+
if (endNumber && typeof endNumber !== "number") {
|
|
116
|
+
endNumber = parseInt(endNumber, 10);
|
|
117
|
+
}
|
|
118
|
+
if (isNaN(endNumber)) {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
return endNumber;
|
|
122
|
+
};
|
|
123
|
+
const segmentRange = {
|
|
124
|
+
/**
|
|
125
|
+
* Returns the entire range of available segments for a static MPD
|
|
126
|
+
*
|
|
127
|
+
* @param {Object} attributes
|
|
128
|
+
* Inheritied MPD attributes
|
|
129
|
+
* @return {{ start: number, end: number }}
|
|
130
|
+
* The start and end numbers for available segments
|
|
131
|
+
*/
|
|
132
|
+
static(attributes) {
|
|
133
|
+
const {
|
|
134
|
+
duration,
|
|
135
|
+
timescale = 1,
|
|
136
|
+
sourceDuration,
|
|
137
|
+
periodDuration
|
|
138
|
+
} = attributes;
|
|
139
|
+
const endNumber = parseEndNumber(attributes.endNumber);
|
|
140
|
+
const segmentDuration = duration / timescale;
|
|
141
|
+
if (typeof endNumber === "number") {
|
|
142
|
+
return {
|
|
143
|
+
start: 0,
|
|
144
|
+
end: endNumber
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
if (typeof periodDuration === "number") {
|
|
148
|
+
return {
|
|
149
|
+
start: 0,
|
|
150
|
+
end: periodDuration / segmentDuration
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
return {
|
|
154
|
+
start: 0,
|
|
155
|
+
end: sourceDuration / segmentDuration
|
|
156
|
+
};
|
|
157
|
+
},
|
|
158
|
+
/**
|
|
159
|
+
* Returns the current live window range of available segments for a dynamic MPD
|
|
160
|
+
*
|
|
161
|
+
* @param {Object} attributes
|
|
162
|
+
* Inheritied MPD attributes
|
|
163
|
+
* @return {{ start: number, end: number }}
|
|
164
|
+
* The start and end numbers for available segments
|
|
165
|
+
*/
|
|
166
|
+
dynamic(attributes) {
|
|
167
|
+
const {
|
|
168
|
+
NOW,
|
|
169
|
+
clientOffset,
|
|
170
|
+
availabilityStartTime,
|
|
171
|
+
timescale = 1,
|
|
172
|
+
duration,
|
|
173
|
+
periodStart = 0,
|
|
174
|
+
minimumUpdatePeriod = 0,
|
|
175
|
+
timeShiftBufferDepth = Infinity
|
|
176
|
+
} = attributes;
|
|
177
|
+
const endNumber = parseEndNumber(attributes.endNumber);
|
|
178
|
+
const now = (NOW + clientOffset) / 1e3;
|
|
179
|
+
const periodStartWC = availabilityStartTime + periodStart;
|
|
180
|
+
const periodEndWC = now + minimumUpdatePeriod;
|
|
181
|
+
const periodDuration = periodEndWC - periodStartWC;
|
|
182
|
+
const segmentCount = Math.ceil(periodDuration * timescale / duration);
|
|
183
|
+
const availableStart = Math.floor((now - periodStartWC - timeShiftBufferDepth) * timescale / duration);
|
|
184
|
+
const availableEnd = Math.floor((now - periodStartWC) * timescale / duration);
|
|
185
|
+
return {
|
|
186
|
+
start: Math.max(0, availableStart),
|
|
187
|
+
end: typeof endNumber === "number" ? endNumber : Math.min(segmentCount, availableEnd)
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
const toSegments = (attributes) => (number) => {
|
|
192
|
+
const {
|
|
193
|
+
duration,
|
|
194
|
+
timescale = 1,
|
|
195
|
+
periodStart,
|
|
196
|
+
startNumber = 1
|
|
197
|
+
} = attributes;
|
|
198
|
+
return {
|
|
199
|
+
number: startNumber + number,
|
|
200
|
+
duration: duration / timescale,
|
|
201
|
+
timeline: periodStart,
|
|
202
|
+
time: number * duration
|
|
203
|
+
};
|
|
204
|
+
};
|
|
205
|
+
const parseByDuration = (attributes) => {
|
|
206
|
+
const {
|
|
207
|
+
type,
|
|
208
|
+
duration,
|
|
209
|
+
timescale = 1,
|
|
210
|
+
periodDuration,
|
|
211
|
+
sourceDuration
|
|
212
|
+
} = attributes;
|
|
213
|
+
const {
|
|
214
|
+
start,
|
|
215
|
+
end
|
|
216
|
+
} = segmentRange[type](attributes);
|
|
217
|
+
const segments = range(start, end).map(toSegments(attributes));
|
|
218
|
+
if (type === "static") {
|
|
219
|
+
const index = segments.length - 1;
|
|
220
|
+
const sectionDuration = typeof periodDuration === "number" ? periodDuration : sourceDuration;
|
|
221
|
+
segments[index].duration = sectionDuration - duration / timescale * index;
|
|
222
|
+
}
|
|
223
|
+
return segments;
|
|
224
|
+
};
|
|
225
|
+
const segmentsFromBase = (attributes) => {
|
|
226
|
+
const {
|
|
227
|
+
baseUrl,
|
|
228
|
+
initialization = {},
|
|
229
|
+
sourceDuration,
|
|
230
|
+
indexRange = "",
|
|
231
|
+
periodStart,
|
|
232
|
+
presentationTime,
|
|
233
|
+
number = 0,
|
|
234
|
+
duration
|
|
235
|
+
} = attributes;
|
|
236
|
+
if (!baseUrl) {
|
|
237
|
+
throw new Error(errors.NO_BASE_URL);
|
|
238
|
+
}
|
|
239
|
+
const initSegment = urlTypeToSegment({
|
|
240
|
+
baseUrl,
|
|
241
|
+
source: initialization.sourceURL,
|
|
242
|
+
range: initialization.range
|
|
243
|
+
});
|
|
244
|
+
const segment = urlTypeToSegment({
|
|
245
|
+
baseUrl,
|
|
246
|
+
source: baseUrl,
|
|
247
|
+
indexRange
|
|
248
|
+
});
|
|
249
|
+
segment.map = initSegment;
|
|
250
|
+
if (duration) {
|
|
251
|
+
const segmentTimeInfo = parseByDuration(attributes);
|
|
252
|
+
if (segmentTimeInfo.length) {
|
|
253
|
+
segment.duration = segmentTimeInfo[0].duration;
|
|
254
|
+
segment.timeline = segmentTimeInfo[0].timeline;
|
|
255
|
+
}
|
|
256
|
+
} else if (sourceDuration) {
|
|
257
|
+
segment.duration = sourceDuration;
|
|
258
|
+
segment.timeline = periodStart;
|
|
259
|
+
}
|
|
260
|
+
segment.presentationTime = presentationTime || periodStart;
|
|
261
|
+
segment.number = number;
|
|
262
|
+
return [segment];
|
|
263
|
+
};
|
|
264
|
+
const addSidxSegmentsToPlaylist$1 = (playlist, sidx, baseUrl) => {
|
|
265
|
+
const initSegment = playlist.sidx.map ? playlist.sidx.map : null;
|
|
266
|
+
const sourceDuration = playlist.sidx.duration;
|
|
267
|
+
const timeline = playlist.timeline || 0;
|
|
268
|
+
const sidxByteRange = playlist.sidx.byterange;
|
|
269
|
+
const sidxEnd = sidxByteRange.offset + sidxByteRange.length;
|
|
270
|
+
const timescale = sidx.timescale;
|
|
271
|
+
const mediaReferences = sidx.references.filter((r) => r.referenceType !== 1);
|
|
272
|
+
const segments = [];
|
|
273
|
+
const type = playlist.endList ? "static" : "dynamic";
|
|
274
|
+
const periodStart = playlist.sidx.timeline;
|
|
275
|
+
let presentationTime = periodStart;
|
|
276
|
+
let number = playlist.mediaSequence || 0;
|
|
277
|
+
let startIndex;
|
|
278
|
+
if (typeof sidx.firstOffset === "bigint") {
|
|
279
|
+
startIndex = window$1.BigInt(sidxEnd) + sidx.firstOffset;
|
|
280
|
+
} else {
|
|
281
|
+
startIndex = sidxEnd + sidx.firstOffset;
|
|
282
|
+
}
|
|
283
|
+
for (let i = 0; i < mediaReferences.length; i++) {
|
|
284
|
+
const reference = sidx.references[i];
|
|
285
|
+
const size = reference.referencedSize;
|
|
286
|
+
const duration = reference.subsegmentDuration;
|
|
287
|
+
let endIndex;
|
|
288
|
+
if (typeof startIndex === "bigint") {
|
|
289
|
+
endIndex = startIndex + window$1.BigInt(size) - window$1.BigInt(1);
|
|
290
|
+
} else {
|
|
291
|
+
endIndex = startIndex + size - 1;
|
|
292
|
+
}
|
|
293
|
+
const indexRange = `${startIndex}-${endIndex}`;
|
|
294
|
+
const attributes = {
|
|
295
|
+
baseUrl,
|
|
296
|
+
timescale,
|
|
297
|
+
timeline,
|
|
298
|
+
periodStart,
|
|
299
|
+
presentationTime,
|
|
300
|
+
number,
|
|
301
|
+
duration,
|
|
302
|
+
sourceDuration,
|
|
303
|
+
indexRange,
|
|
304
|
+
type
|
|
305
|
+
};
|
|
306
|
+
const segment = segmentsFromBase(attributes)[0];
|
|
307
|
+
if (initSegment) {
|
|
308
|
+
segment.map = initSegment;
|
|
309
|
+
}
|
|
310
|
+
segments.push(segment);
|
|
311
|
+
if (typeof startIndex === "bigint") {
|
|
312
|
+
startIndex += window$1.BigInt(size);
|
|
313
|
+
} else {
|
|
314
|
+
startIndex += size;
|
|
315
|
+
}
|
|
316
|
+
presentationTime += duration / timescale;
|
|
317
|
+
number++;
|
|
318
|
+
}
|
|
319
|
+
playlist.segments = segments;
|
|
320
|
+
return playlist;
|
|
321
|
+
};
|
|
322
|
+
const SUPPORTED_MEDIA_TYPES = ["AUDIO", "SUBTITLES"];
|
|
323
|
+
const TIME_FUDGE = 1 / 60;
|
|
324
|
+
const getUniqueTimelineStarts = (timelineStarts) => {
|
|
325
|
+
return union(timelineStarts, ({
|
|
326
|
+
timeline
|
|
327
|
+
}) => timeline).sort((a, b) => a.timeline > b.timeline ? 1 : -1);
|
|
328
|
+
};
|
|
329
|
+
const findPlaylistWithName = (playlists, name) => {
|
|
330
|
+
for (let i = 0; i < playlists.length; i++) {
|
|
331
|
+
if (playlists[i].attributes.NAME === name) {
|
|
332
|
+
return playlists[i];
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
return null;
|
|
336
|
+
};
|
|
337
|
+
const getMediaGroupPlaylists = (manifest) => {
|
|
338
|
+
let mediaGroupPlaylists = [];
|
|
339
|
+
forEachMediaGroup(manifest, SUPPORTED_MEDIA_TYPES, (properties, type, group, label) => {
|
|
340
|
+
mediaGroupPlaylists = mediaGroupPlaylists.concat(properties.playlists || []);
|
|
341
|
+
});
|
|
342
|
+
return mediaGroupPlaylists;
|
|
343
|
+
};
|
|
344
|
+
const updateMediaSequenceForPlaylist = ({
|
|
345
|
+
playlist,
|
|
346
|
+
mediaSequence
|
|
347
|
+
}) => {
|
|
348
|
+
playlist.mediaSequence = mediaSequence;
|
|
349
|
+
playlist.segments.forEach((segment, index) => {
|
|
350
|
+
segment.number = playlist.mediaSequence + index;
|
|
351
|
+
});
|
|
352
|
+
};
|
|
353
|
+
const updateSequenceNumbers = ({
|
|
354
|
+
oldPlaylists,
|
|
355
|
+
newPlaylists,
|
|
356
|
+
timelineStarts
|
|
357
|
+
}) => {
|
|
358
|
+
newPlaylists.forEach((playlist) => {
|
|
359
|
+
playlist.discontinuitySequence = timelineStarts.findIndex(function({
|
|
360
|
+
timeline
|
|
361
|
+
}) {
|
|
362
|
+
return timeline === playlist.timeline;
|
|
363
|
+
});
|
|
364
|
+
const oldPlaylist = findPlaylistWithName(oldPlaylists, playlist.attributes.NAME);
|
|
365
|
+
if (!oldPlaylist) {
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
if (playlist.sidx) {
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
const firstNewSegment = playlist.segments[0];
|
|
372
|
+
const oldMatchingSegmentIndex = oldPlaylist.segments.findIndex(function(oldSegment) {
|
|
373
|
+
return Math.abs(oldSegment.presentationTime - firstNewSegment.presentationTime) < TIME_FUDGE;
|
|
374
|
+
});
|
|
375
|
+
if (oldMatchingSegmentIndex === -1) {
|
|
376
|
+
updateMediaSequenceForPlaylist({
|
|
377
|
+
playlist,
|
|
378
|
+
mediaSequence: oldPlaylist.mediaSequence + oldPlaylist.segments.length
|
|
379
|
+
});
|
|
380
|
+
playlist.segments[0].discontinuity = true;
|
|
381
|
+
playlist.discontinuityStarts.unshift(0);
|
|
382
|
+
if (!oldPlaylist.segments.length && playlist.timeline > oldPlaylist.timeline || oldPlaylist.segments.length && playlist.timeline > oldPlaylist.segments[oldPlaylist.segments.length - 1].timeline) {
|
|
383
|
+
playlist.discontinuitySequence--;
|
|
384
|
+
}
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
const oldMatchingSegment = oldPlaylist.segments[oldMatchingSegmentIndex];
|
|
388
|
+
if (oldMatchingSegment.discontinuity && !firstNewSegment.discontinuity) {
|
|
389
|
+
firstNewSegment.discontinuity = true;
|
|
390
|
+
playlist.discontinuityStarts.unshift(0);
|
|
391
|
+
playlist.discontinuitySequence--;
|
|
392
|
+
}
|
|
393
|
+
updateMediaSequenceForPlaylist({
|
|
394
|
+
playlist,
|
|
395
|
+
mediaSequence: oldPlaylist.segments[oldMatchingSegmentIndex].number
|
|
396
|
+
});
|
|
397
|
+
});
|
|
398
|
+
};
|
|
399
|
+
const positionManifestOnTimeline = ({
|
|
400
|
+
oldManifest,
|
|
401
|
+
newManifest
|
|
402
|
+
}) => {
|
|
403
|
+
const oldPlaylists = oldManifest.playlists.concat(getMediaGroupPlaylists(oldManifest));
|
|
404
|
+
const newPlaylists = newManifest.playlists.concat(getMediaGroupPlaylists(newManifest));
|
|
405
|
+
newManifest.timelineStarts = getUniqueTimelineStarts([oldManifest.timelineStarts, newManifest.timelineStarts]);
|
|
406
|
+
updateSequenceNumbers({
|
|
407
|
+
oldPlaylists,
|
|
408
|
+
newPlaylists,
|
|
409
|
+
timelineStarts: newManifest.timelineStarts
|
|
410
|
+
});
|
|
411
|
+
return newManifest;
|
|
412
|
+
};
|
|
413
|
+
const generateSidxKey = (sidx) => sidx && sidx.uri + "-" + byteRangeToString(sidx.byterange);
|
|
414
|
+
const mergeDiscontiguousPlaylists = (playlists) => {
|
|
415
|
+
const playlistsByBaseUrl = playlists.reduce(function(acc, cur) {
|
|
416
|
+
if (!acc[cur.attributes.baseUrl]) {
|
|
417
|
+
acc[cur.attributes.baseUrl] = [];
|
|
418
|
+
}
|
|
419
|
+
acc[cur.attributes.baseUrl].push(cur);
|
|
420
|
+
return acc;
|
|
421
|
+
}, {});
|
|
422
|
+
let allPlaylists = [];
|
|
423
|
+
Object.values(playlistsByBaseUrl).forEach((playlistGroup) => {
|
|
424
|
+
const mergedPlaylists = values(playlistGroup.reduce((acc, playlist) => {
|
|
425
|
+
const name = playlist.attributes.id + (playlist.attributes.lang || "");
|
|
426
|
+
if (!acc[name]) {
|
|
427
|
+
acc[name] = playlist;
|
|
428
|
+
acc[name].attributes.timelineStarts = [];
|
|
429
|
+
} else {
|
|
430
|
+
if (playlist.segments) {
|
|
431
|
+
if (playlist.segments[0]) {
|
|
432
|
+
playlist.segments[0].discontinuity = true;
|
|
433
|
+
}
|
|
434
|
+
acc[name].segments.push(...playlist.segments);
|
|
435
|
+
}
|
|
436
|
+
if (playlist.attributes.contentProtection) {
|
|
437
|
+
acc[name].attributes.contentProtection = playlist.attributes.contentProtection;
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
acc[name].attributes.timelineStarts.push({
|
|
441
|
+
// Although they represent the same number, it's important to have both to make it
|
|
442
|
+
// compatible with HLS potentially having a similar attribute.
|
|
443
|
+
start: playlist.attributes.periodStart,
|
|
444
|
+
timeline: playlist.attributes.periodStart
|
|
445
|
+
});
|
|
446
|
+
return acc;
|
|
447
|
+
}, {}));
|
|
448
|
+
allPlaylists = allPlaylists.concat(mergedPlaylists);
|
|
449
|
+
});
|
|
450
|
+
return allPlaylists.map((playlist) => {
|
|
451
|
+
playlist.discontinuityStarts = findIndexes(playlist.segments || [], "discontinuity");
|
|
452
|
+
return playlist;
|
|
453
|
+
});
|
|
454
|
+
};
|
|
455
|
+
const addSidxSegmentsToPlaylist = (playlist, sidxMapping) => {
|
|
456
|
+
const sidxKey = generateSidxKey(playlist.sidx);
|
|
457
|
+
const sidxMatch = sidxKey && sidxMapping[sidxKey] && sidxMapping[sidxKey].sidx;
|
|
458
|
+
if (sidxMatch) {
|
|
459
|
+
addSidxSegmentsToPlaylist$1(playlist, sidxMatch, playlist.sidx.resolvedUri);
|
|
460
|
+
}
|
|
461
|
+
return playlist;
|
|
462
|
+
};
|
|
463
|
+
const addSidxSegmentsToPlaylists = (playlists, sidxMapping = {}) => {
|
|
464
|
+
if (!Object.keys(sidxMapping).length) {
|
|
465
|
+
return playlists;
|
|
466
|
+
}
|
|
467
|
+
for (const i in playlists) {
|
|
468
|
+
playlists[i] = addSidxSegmentsToPlaylist(playlists[i], sidxMapping);
|
|
469
|
+
}
|
|
470
|
+
return playlists;
|
|
471
|
+
};
|
|
472
|
+
const formatAudioPlaylist = ({
|
|
473
|
+
attributes,
|
|
474
|
+
segments,
|
|
475
|
+
sidx,
|
|
476
|
+
mediaSequence,
|
|
477
|
+
discontinuitySequence,
|
|
478
|
+
discontinuityStarts
|
|
479
|
+
}, isAudioOnly) => {
|
|
480
|
+
const playlist = {
|
|
481
|
+
attributes: {
|
|
482
|
+
NAME: attributes.id,
|
|
483
|
+
BANDWIDTH: attributes.bandwidth,
|
|
484
|
+
CODECS: attributes.codecs,
|
|
485
|
+
["PROGRAM-ID"]: 1
|
|
486
|
+
},
|
|
487
|
+
uri: "",
|
|
488
|
+
endList: attributes.type === "static",
|
|
489
|
+
timeline: attributes.periodStart,
|
|
490
|
+
resolvedUri: attributes.baseUrl || "",
|
|
491
|
+
targetDuration: attributes.duration,
|
|
492
|
+
discontinuitySequence,
|
|
493
|
+
discontinuityStarts,
|
|
494
|
+
timelineStarts: attributes.timelineStarts,
|
|
495
|
+
mediaSequence,
|
|
496
|
+
segments
|
|
497
|
+
};
|
|
498
|
+
if (attributes.contentProtection) {
|
|
499
|
+
playlist.contentProtection = attributes.contentProtection;
|
|
500
|
+
}
|
|
501
|
+
if (attributes.serviceLocation) {
|
|
502
|
+
playlist.attributes.serviceLocation = attributes.serviceLocation;
|
|
503
|
+
}
|
|
504
|
+
if (sidx) {
|
|
505
|
+
playlist.sidx = sidx;
|
|
506
|
+
}
|
|
507
|
+
if (isAudioOnly) {
|
|
508
|
+
playlist.attributes.AUDIO = "audio";
|
|
509
|
+
playlist.attributes.SUBTITLES = "subs";
|
|
510
|
+
}
|
|
511
|
+
return playlist;
|
|
512
|
+
};
|
|
513
|
+
const formatVttPlaylist = ({
|
|
514
|
+
attributes,
|
|
515
|
+
segments,
|
|
516
|
+
mediaSequence,
|
|
517
|
+
discontinuityStarts,
|
|
518
|
+
discontinuitySequence
|
|
519
|
+
}) => {
|
|
520
|
+
if (typeof segments === "undefined") {
|
|
521
|
+
segments = [{
|
|
522
|
+
uri: attributes.baseUrl,
|
|
523
|
+
timeline: attributes.periodStart,
|
|
524
|
+
resolvedUri: attributes.baseUrl || "",
|
|
525
|
+
duration: attributes.sourceDuration,
|
|
526
|
+
number: 0
|
|
527
|
+
}];
|
|
528
|
+
attributes.duration = attributes.sourceDuration;
|
|
529
|
+
}
|
|
530
|
+
const m3u8Attributes = {
|
|
531
|
+
NAME: attributes.id,
|
|
532
|
+
BANDWIDTH: attributes.bandwidth,
|
|
533
|
+
["PROGRAM-ID"]: 1
|
|
534
|
+
};
|
|
535
|
+
if (attributes.codecs) {
|
|
536
|
+
m3u8Attributes.CODECS = attributes.codecs;
|
|
537
|
+
}
|
|
538
|
+
const vttPlaylist = {
|
|
539
|
+
attributes: m3u8Attributes,
|
|
540
|
+
uri: "",
|
|
541
|
+
endList: attributes.type === "static",
|
|
542
|
+
timeline: attributes.periodStart,
|
|
543
|
+
resolvedUri: attributes.baseUrl || "",
|
|
544
|
+
targetDuration: attributes.duration,
|
|
545
|
+
timelineStarts: attributes.timelineStarts,
|
|
546
|
+
discontinuityStarts,
|
|
547
|
+
discontinuitySequence,
|
|
548
|
+
mediaSequence,
|
|
549
|
+
segments
|
|
550
|
+
};
|
|
551
|
+
if (attributes.serviceLocation) {
|
|
552
|
+
vttPlaylist.attributes.serviceLocation = attributes.serviceLocation;
|
|
553
|
+
}
|
|
554
|
+
return vttPlaylist;
|
|
555
|
+
};
|
|
556
|
+
const organizeAudioPlaylists = (playlists, sidxMapping = {}, isAudioOnly = false) => {
|
|
557
|
+
let mainPlaylist;
|
|
558
|
+
const formattedPlaylists = playlists.reduce((a, playlist) => {
|
|
559
|
+
const role = playlist.attributes.role && playlist.attributes.role.value || "";
|
|
560
|
+
const language = playlist.attributes.lang || "";
|
|
561
|
+
let label = playlist.attributes.label || "main";
|
|
562
|
+
if (language && !playlist.attributes.label) {
|
|
563
|
+
const roleLabel = role ? ` (${role})` : "";
|
|
564
|
+
label = `${playlist.attributes.lang}${roleLabel}`;
|
|
565
|
+
}
|
|
566
|
+
if (!a[label]) {
|
|
567
|
+
a[label] = {
|
|
568
|
+
language,
|
|
569
|
+
autoselect: true,
|
|
570
|
+
default: role === "main",
|
|
571
|
+
playlists: [],
|
|
572
|
+
uri: ""
|
|
573
|
+
};
|
|
574
|
+
}
|
|
575
|
+
const formatted = addSidxSegmentsToPlaylist(formatAudioPlaylist(playlist, isAudioOnly), sidxMapping);
|
|
576
|
+
a[label].playlists.push(formatted);
|
|
577
|
+
if (typeof mainPlaylist === "undefined" && role === "main") {
|
|
578
|
+
mainPlaylist = playlist;
|
|
579
|
+
mainPlaylist.default = true;
|
|
580
|
+
}
|
|
581
|
+
return a;
|
|
582
|
+
}, {});
|
|
583
|
+
if (!mainPlaylist) {
|
|
584
|
+
const firstLabel = Object.keys(formattedPlaylists)[0];
|
|
585
|
+
formattedPlaylists[firstLabel].default = true;
|
|
586
|
+
}
|
|
587
|
+
return formattedPlaylists;
|
|
588
|
+
};
|
|
589
|
+
const organizeVttPlaylists = (playlists, sidxMapping = {}) => {
|
|
590
|
+
return playlists.reduce((a, playlist) => {
|
|
591
|
+
const label = playlist.attributes.label || playlist.attributes.lang || "text";
|
|
592
|
+
const language = playlist.attributes.lang || "und";
|
|
593
|
+
if (!a[label]) {
|
|
594
|
+
a[label] = {
|
|
595
|
+
language,
|
|
596
|
+
default: false,
|
|
597
|
+
autoselect: false,
|
|
598
|
+
playlists: [],
|
|
599
|
+
uri: ""
|
|
600
|
+
};
|
|
601
|
+
}
|
|
602
|
+
a[label].playlists.push(addSidxSegmentsToPlaylist(formatVttPlaylist(playlist), sidxMapping));
|
|
603
|
+
return a;
|
|
604
|
+
}, {});
|
|
605
|
+
};
|
|
606
|
+
const organizeCaptionServices = (captionServices) => captionServices.reduce((svcObj, svc) => {
|
|
607
|
+
if (!svc) {
|
|
608
|
+
return svcObj;
|
|
609
|
+
}
|
|
610
|
+
svc.forEach((service) => {
|
|
611
|
+
const {
|
|
612
|
+
channel,
|
|
613
|
+
language
|
|
614
|
+
} = service;
|
|
615
|
+
svcObj[language] = {
|
|
616
|
+
autoselect: false,
|
|
617
|
+
default: false,
|
|
618
|
+
instreamId: channel,
|
|
619
|
+
language
|
|
620
|
+
};
|
|
621
|
+
if (service.hasOwnProperty("aspectRatio")) {
|
|
622
|
+
svcObj[language].aspectRatio = service.aspectRatio;
|
|
623
|
+
}
|
|
624
|
+
if (service.hasOwnProperty("easyReader")) {
|
|
625
|
+
svcObj[language].easyReader = service.easyReader;
|
|
626
|
+
}
|
|
627
|
+
if (service.hasOwnProperty("3D")) {
|
|
628
|
+
svcObj[language]["3D"] = service["3D"];
|
|
629
|
+
}
|
|
630
|
+
});
|
|
631
|
+
return svcObj;
|
|
632
|
+
}, {});
|
|
633
|
+
const formatVideoPlaylist = ({
|
|
634
|
+
attributes,
|
|
635
|
+
segments,
|
|
636
|
+
sidx,
|
|
637
|
+
discontinuityStarts
|
|
638
|
+
}) => {
|
|
639
|
+
const playlist = {
|
|
640
|
+
attributes: {
|
|
641
|
+
NAME: attributes.id,
|
|
642
|
+
AUDIO: "audio",
|
|
643
|
+
SUBTITLES: "subs",
|
|
644
|
+
RESOLUTION: {
|
|
645
|
+
width: attributes.width,
|
|
646
|
+
height: attributes.height
|
|
647
|
+
},
|
|
648
|
+
CODECS: attributes.codecs,
|
|
649
|
+
BANDWIDTH: attributes.bandwidth,
|
|
650
|
+
["PROGRAM-ID"]: 1
|
|
651
|
+
},
|
|
652
|
+
uri: "",
|
|
653
|
+
endList: attributes.type === "static",
|
|
654
|
+
timeline: attributes.periodStart,
|
|
655
|
+
resolvedUri: attributes.baseUrl || "",
|
|
656
|
+
targetDuration: attributes.duration,
|
|
657
|
+
discontinuityStarts,
|
|
658
|
+
timelineStarts: attributes.timelineStarts,
|
|
659
|
+
segments
|
|
660
|
+
};
|
|
661
|
+
if (attributes.frameRate) {
|
|
662
|
+
playlist.attributes["FRAME-RATE"] = attributes.frameRate;
|
|
663
|
+
}
|
|
664
|
+
if (attributes.contentProtection) {
|
|
665
|
+
playlist.contentProtection = attributes.contentProtection;
|
|
666
|
+
}
|
|
667
|
+
if (attributes.serviceLocation) {
|
|
668
|
+
playlist.attributes.serviceLocation = attributes.serviceLocation;
|
|
669
|
+
}
|
|
670
|
+
if (sidx) {
|
|
671
|
+
playlist.sidx = sidx;
|
|
672
|
+
}
|
|
673
|
+
return playlist;
|
|
674
|
+
};
|
|
675
|
+
const videoOnly = ({
|
|
676
|
+
attributes
|
|
677
|
+
}) => attributes.mimeType === "video/mp4" || attributes.mimeType === "video/webm" || attributes.contentType === "video";
|
|
678
|
+
const audioOnly = ({
|
|
679
|
+
attributes
|
|
680
|
+
}) => attributes.mimeType === "audio/mp4" || attributes.mimeType === "audio/webm" || attributes.contentType === "audio";
|
|
681
|
+
const vttOnly = ({
|
|
682
|
+
attributes
|
|
683
|
+
}) => attributes.mimeType === "text/vtt" || attributes.contentType === "text";
|
|
684
|
+
const addMediaSequenceValues = (playlists, timelineStarts) => {
|
|
685
|
+
playlists.forEach((playlist) => {
|
|
686
|
+
playlist.mediaSequence = 0;
|
|
687
|
+
playlist.discontinuitySequence = timelineStarts.findIndex(function({
|
|
688
|
+
timeline
|
|
689
|
+
}) {
|
|
690
|
+
return timeline === playlist.timeline;
|
|
691
|
+
});
|
|
692
|
+
if (!playlist.segments) {
|
|
693
|
+
return;
|
|
694
|
+
}
|
|
695
|
+
playlist.segments.forEach((segment, index) => {
|
|
696
|
+
segment.number = index;
|
|
697
|
+
});
|
|
698
|
+
});
|
|
699
|
+
};
|
|
700
|
+
const flattenMediaGroupPlaylists = (mediaGroupObject) => {
|
|
701
|
+
if (!mediaGroupObject) {
|
|
702
|
+
return [];
|
|
703
|
+
}
|
|
704
|
+
return Object.keys(mediaGroupObject).reduce((acc, label) => {
|
|
705
|
+
const labelContents = mediaGroupObject[label];
|
|
706
|
+
return acc.concat(labelContents.playlists);
|
|
707
|
+
}, []);
|
|
708
|
+
};
|
|
709
|
+
const toM3u8 = ({
|
|
710
|
+
dashPlaylists,
|
|
711
|
+
locations,
|
|
712
|
+
contentSteering,
|
|
713
|
+
sidxMapping = {},
|
|
714
|
+
previousManifest,
|
|
715
|
+
eventStream
|
|
716
|
+
}) => {
|
|
717
|
+
if (!dashPlaylists.length) {
|
|
718
|
+
return {};
|
|
719
|
+
}
|
|
720
|
+
const {
|
|
721
|
+
sourceDuration: duration,
|
|
722
|
+
type,
|
|
723
|
+
suggestedPresentationDelay,
|
|
724
|
+
minimumUpdatePeriod
|
|
725
|
+
} = dashPlaylists[0].attributes;
|
|
726
|
+
const videoPlaylists = mergeDiscontiguousPlaylists(dashPlaylists.filter(videoOnly)).map(formatVideoPlaylist);
|
|
727
|
+
const audioPlaylists = mergeDiscontiguousPlaylists(dashPlaylists.filter(audioOnly));
|
|
728
|
+
const vttPlaylists = mergeDiscontiguousPlaylists(dashPlaylists.filter(vttOnly));
|
|
729
|
+
const captions = dashPlaylists.map((playlist) => playlist.attributes.captionServices).filter(Boolean);
|
|
730
|
+
const manifest = {
|
|
731
|
+
allowCache: true,
|
|
732
|
+
discontinuityStarts: [],
|
|
733
|
+
segments: [],
|
|
734
|
+
endList: true,
|
|
735
|
+
mediaGroups: {
|
|
736
|
+
AUDIO: {},
|
|
737
|
+
VIDEO: {},
|
|
738
|
+
["CLOSED-CAPTIONS"]: {},
|
|
739
|
+
SUBTITLES: {}
|
|
740
|
+
},
|
|
741
|
+
uri: "",
|
|
742
|
+
duration,
|
|
743
|
+
playlists: addSidxSegmentsToPlaylists(videoPlaylists, sidxMapping)
|
|
744
|
+
};
|
|
745
|
+
if (minimumUpdatePeriod >= 0) {
|
|
746
|
+
manifest.minimumUpdatePeriod = minimumUpdatePeriod * 1e3;
|
|
747
|
+
}
|
|
748
|
+
if (locations) {
|
|
749
|
+
manifest.locations = locations;
|
|
750
|
+
}
|
|
751
|
+
if (contentSteering) {
|
|
752
|
+
manifest.contentSteering = contentSteering;
|
|
753
|
+
}
|
|
754
|
+
if (type === "dynamic") {
|
|
755
|
+
manifest.suggestedPresentationDelay = suggestedPresentationDelay;
|
|
756
|
+
}
|
|
757
|
+
if (eventStream && eventStream.length > 0) {
|
|
758
|
+
manifest.eventStream = eventStream;
|
|
759
|
+
}
|
|
760
|
+
const isAudioOnly = manifest.playlists.length === 0;
|
|
761
|
+
const organizedAudioGroup = audioPlaylists.length ? organizeAudioPlaylists(audioPlaylists, sidxMapping, isAudioOnly) : null;
|
|
762
|
+
const organizedVttGroup = vttPlaylists.length ? organizeVttPlaylists(vttPlaylists, sidxMapping) : null;
|
|
763
|
+
const formattedPlaylists = videoPlaylists.concat(flattenMediaGroupPlaylists(organizedAudioGroup), flattenMediaGroupPlaylists(organizedVttGroup));
|
|
764
|
+
const playlistTimelineStarts = formattedPlaylists.map(({
|
|
765
|
+
timelineStarts
|
|
766
|
+
}) => timelineStarts);
|
|
767
|
+
manifest.timelineStarts = getUniqueTimelineStarts(playlistTimelineStarts);
|
|
768
|
+
addMediaSequenceValues(formattedPlaylists, manifest.timelineStarts);
|
|
769
|
+
if (organizedAudioGroup) {
|
|
770
|
+
manifest.mediaGroups.AUDIO.audio = organizedAudioGroup;
|
|
771
|
+
}
|
|
772
|
+
if (organizedVttGroup) {
|
|
773
|
+
manifest.mediaGroups.SUBTITLES.subs = organizedVttGroup;
|
|
774
|
+
}
|
|
775
|
+
if (captions.length) {
|
|
776
|
+
manifest.mediaGroups["CLOSED-CAPTIONS"].cc = organizeCaptionServices(captions);
|
|
777
|
+
}
|
|
778
|
+
if (previousManifest) {
|
|
779
|
+
return positionManifestOnTimeline({
|
|
780
|
+
oldManifest: previousManifest,
|
|
781
|
+
newManifest: manifest
|
|
782
|
+
});
|
|
783
|
+
}
|
|
784
|
+
return manifest;
|
|
785
|
+
};
|
|
786
|
+
const getLiveRValue = (attributes, time, duration) => {
|
|
787
|
+
const {
|
|
788
|
+
NOW,
|
|
789
|
+
clientOffset,
|
|
790
|
+
availabilityStartTime,
|
|
791
|
+
timescale = 1,
|
|
792
|
+
periodStart = 0,
|
|
793
|
+
minimumUpdatePeriod = 0
|
|
794
|
+
} = attributes;
|
|
795
|
+
const now = (NOW + clientOffset) / 1e3;
|
|
796
|
+
const periodStartWC = availabilityStartTime + periodStart;
|
|
797
|
+
const periodEndWC = now + minimumUpdatePeriod;
|
|
798
|
+
const periodDuration = periodEndWC - periodStartWC;
|
|
799
|
+
return Math.ceil((periodDuration * timescale - time) / duration);
|
|
800
|
+
};
|
|
801
|
+
const parseByTimeline = (attributes, segmentTimeline) => {
|
|
802
|
+
const {
|
|
803
|
+
type,
|
|
804
|
+
minimumUpdatePeriod = 0,
|
|
805
|
+
media = "",
|
|
806
|
+
sourceDuration,
|
|
807
|
+
timescale = 1,
|
|
808
|
+
startNumber = 1,
|
|
809
|
+
periodStart: timeline
|
|
810
|
+
} = attributes;
|
|
811
|
+
const segments = [];
|
|
812
|
+
let time = -1;
|
|
813
|
+
for (let sIndex = 0; sIndex < segmentTimeline.length; sIndex++) {
|
|
814
|
+
const S = segmentTimeline[sIndex];
|
|
815
|
+
const duration = S.d;
|
|
816
|
+
const repeat = S.r || 0;
|
|
817
|
+
const segmentTime = S.t || 0;
|
|
818
|
+
if (time < 0) {
|
|
819
|
+
time = segmentTime;
|
|
820
|
+
}
|
|
821
|
+
if (segmentTime && segmentTime > time) {
|
|
822
|
+
time = segmentTime;
|
|
823
|
+
}
|
|
824
|
+
let count;
|
|
825
|
+
if (repeat < 0) {
|
|
826
|
+
const nextS = sIndex + 1;
|
|
827
|
+
if (nextS === segmentTimeline.length) {
|
|
828
|
+
if (type === "dynamic" && minimumUpdatePeriod > 0 && media.indexOf("$Number$") > 0) {
|
|
829
|
+
count = getLiveRValue(attributes, time, duration);
|
|
830
|
+
} else {
|
|
831
|
+
count = (sourceDuration * timescale - time) / duration;
|
|
832
|
+
}
|
|
833
|
+
} else {
|
|
834
|
+
count = (segmentTimeline[nextS].t - time) / duration;
|
|
835
|
+
}
|
|
836
|
+
} else {
|
|
837
|
+
count = repeat + 1;
|
|
838
|
+
}
|
|
839
|
+
const end = startNumber + segments.length + count;
|
|
840
|
+
let number = startNumber + segments.length;
|
|
841
|
+
while (number < end) {
|
|
842
|
+
segments.push({
|
|
843
|
+
number,
|
|
844
|
+
duration: duration / timescale,
|
|
845
|
+
time,
|
|
846
|
+
timeline
|
|
847
|
+
});
|
|
848
|
+
time += duration;
|
|
849
|
+
number++;
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
return segments;
|
|
853
|
+
};
|
|
854
|
+
const identifierPattern = /\$([A-z]*)(?:(%0)([0-9]+)d)?\$/g;
|
|
855
|
+
const identifierReplacement = (values2) => (match, identifier, format, width) => {
|
|
856
|
+
if (match === "$$") {
|
|
857
|
+
return "$";
|
|
858
|
+
}
|
|
859
|
+
if (typeof values2[identifier] === "undefined") {
|
|
860
|
+
return match;
|
|
861
|
+
}
|
|
862
|
+
const value = "" + values2[identifier];
|
|
863
|
+
if (identifier === "RepresentationID") {
|
|
864
|
+
return value;
|
|
865
|
+
}
|
|
866
|
+
if (!format) {
|
|
867
|
+
width = 1;
|
|
868
|
+
} else {
|
|
869
|
+
width = parseInt(width, 10);
|
|
870
|
+
}
|
|
871
|
+
if (value.length >= width) {
|
|
872
|
+
return value;
|
|
873
|
+
}
|
|
874
|
+
return `${new Array(width - value.length + 1).join("0")}${value}`;
|
|
875
|
+
};
|
|
876
|
+
const constructTemplateUrl = (url, values2) => url.replace(identifierPattern, identifierReplacement(values2));
|
|
877
|
+
const parseTemplateInfo = (attributes, segmentTimeline) => {
|
|
878
|
+
if (!attributes.duration && !segmentTimeline) {
|
|
879
|
+
return [{
|
|
880
|
+
number: attributes.startNumber || 1,
|
|
881
|
+
duration: attributes.sourceDuration,
|
|
882
|
+
time: 0,
|
|
883
|
+
timeline: attributes.periodStart
|
|
884
|
+
}];
|
|
885
|
+
}
|
|
886
|
+
if (attributes.duration) {
|
|
887
|
+
return parseByDuration(attributes);
|
|
888
|
+
}
|
|
889
|
+
return parseByTimeline(attributes, segmentTimeline);
|
|
890
|
+
};
|
|
891
|
+
const segmentsFromTemplate = (attributes, segmentTimeline) => {
|
|
892
|
+
const templateValues = {
|
|
893
|
+
RepresentationID: attributes.id,
|
|
894
|
+
Bandwidth: attributes.bandwidth || 0
|
|
895
|
+
};
|
|
896
|
+
const {
|
|
897
|
+
initialization = {
|
|
898
|
+
sourceURL: "",
|
|
899
|
+
range: ""
|
|
900
|
+
}
|
|
901
|
+
} = attributes;
|
|
902
|
+
const mapSegment = urlTypeToSegment({
|
|
903
|
+
baseUrl: attributes.baseUrl,
|
|
904
|
+
source: constructTemplateUrl(initialization.sourceURL, templateValues),
|
|
905
|
+
range: initialization.range
|
|
906
|
+
});
|
|
907
|
+
const segments = parseTemplateInfo(attributes, segmentTimeline);
|
|
908
|
+
return segments.map((segment) => {
|
|
909
|
+
templateValues.Number = segment.number;
|
|
910
|
+
templateValues.Time = segment.time;
|
|
911
|
+
const uri = constructTemplateUrl(attributes.media || "", templateValues);
|
|
912
|
+
const timescale = attributes.timescale || 1;
|
|
913
|
+
const presentationTimeOffset = attributes.presentationTimeOffset || 0;
|
|
914
|
+
const presentationTime = (
|
|
915
|
+
// Even if the @t attribute is not specified for the segment, segment.time is
|
|
916
|
+
// calculated in mpd-parser prior to this, so it's assumed to be available.
|
|
917
|
+
attributes.periodStart + (segment.time - presentationTimeOffset) / timescale
|
|
918
|
+
);
|
|
919
|
+
const map = {
|
|
920
|
+
uri,
|
|
921
|
+
timeline: segment.timeline,
|
|
922
|
+
duration: segment.duration,
|
|
923
|
+
resolvedUri: resolveUrl(attributes.baseUrl || "", uri),
|
|
924
|
+
map: mapSegment,
|
|
925
|
+
number: segment.number,
|
|
926
|
+
presentationTime
|
|
927
|
+
};
|
|
928
|
+
return map;
|
|
929
|
+
});
|
|
930
|
+
};
|
|
931
|
+
const SegmentURLToSegmentObject = (attributes, segmentUrl) => {
|
|
932
|
+
const {
|
|
933
|
+
baseUrl,
|
|
934
|
+
initialization = {}
|
|
935
|
+
} = attributes;
|
|
936
|
+
const initSegment = urlTypeToSegment({
|
|
937
|
+
baseUrl,
|
|
938
|
+
source: initialization.sourceURL,
|
|
939
|
+
range: initialization.range
|
|
940
|
+
});
|
|
941
|
+
const segment = urlTypeToSegment({
|
|
942
|
+
baseUrl,
|
|
943
|
+
source: segmentUrl.media,
|
|
944
|
+
range: segmentUrl.mediaRange
|
|
945
|
+
});
|
|
946
|
+
segment.map = initSegment;
|
|
947
|
+
return segment;
|
|
948
|
+
};
|
|
949
|
+
const segmentsFromList = (attributes, segmentTimeline) => {
|
|
950
|
+
const {
|
|
951
|
+
duration,
|
|
952
|
+
segmentUrls = [],
|
|
953
|
+
periodStart
|
|
954
|
+
} = attributes;
|
|
955
|
+
if (!duration && !segmentTimeline || duration && segmentTimeline) {
|
|
956
|
+
throw new Error(errors.SEGMENT_TIME_UNSPECIFIED);
|
|
957
|
+
}
|
|
958
|
+
const segmentUrlMap = segmentUrls.map((segmentUrlObject) => SegmentURLToSegmentObject(attributes, segmentUrlObject));
|
|
959
|
+
let segmentTimeInfo;
|
|
960
|
+
if (duration) {
|
|
961
|
+
segmentTimeInfo = parseByDuration(attributes);
|
|
962
|
+
}
|
|
963
|
+
if (segmentTimeline) {
|
|
964
|
+
segmentTimeInfo = parseByTimeline(attributes, segmentTimeline);
|
|
965
|
+
}
|
|
966
|
+
const segments = segmentTimeInfo.map((segmentTime, index) => {
|
|
967
|
+
if (segmentUrlMap[index]) {
|
|
968
|
+
const segment = segmentUrlMap[index];
|
|
969
|
+
const timescale = attributes.timescale || 1;
|
|
970
|
+
const presentationTimeOffset = attributes.presentationTimeOffset || 0;
|
|
971
|
+
segment.timeline = segmentTime.timeline;
|
|
972
|
+
segment.duration = segmentTime.duration;
|
|
973
|
+
segment.number = segmentTime.number;
|
|
974
|
+
segment.presentationTime = periodStart + (segmentTime.time - presentationTimeOffset) / timescale;
|
|
975
|
+
return segment;
|
|
976
|
+
}
|
|
977
|
+
}).filter((segment) => segment);
|
|
978
|
+
return segments;
|
|
979
|
+
};
|
|
980
|
+
const generateSegments = ({
|
|
981
|
+
attributes,
|
|
982
|
+
segmentInfo
|
|
983
|
+
}) => {
|
|
984
|
+
let segmentAttributes;
|
|
985
|
+
let segmentsFn;
|
|
986
|
+
if (segmentInfo.template) {
|
|
987
|
+
segmentsFn = segmentsFromTemplate;
|
|
988
|
+
segmentAttributes = merge(attributes, segmentInfo.template);
|
|
989
|
+
} else if (segmentInfo.base) {
|
|
990
|
+
segmentsFn = segmentsFromBase;
|
|
991
|
+
segmentAttributes = merge(attributes, segmentInfo.base);
|
|
992
|
+
} else if (segmentInfo.list) {
|
|
993
|
+
segmentsFn = segmentsFromList;
|
|
994
|
+
segmentAttributes = merge(attributes, segmentInfo.list);
|
|
995
|
+
}
|
|
996
|
+
const segmentsInfo = {
|
|
997
|
+
attributes
|
|
998
|
+
};
|
|
999
|
+
if (!segmentsFn) {
|
|
1000
|
+
return segmentsInfo;
|
|
1001
|
+
}
|
|
1002
|
+
const segments = segmentsFn(segmentAttributes, segmentInfo.segmentTimeline);
|
|
1003
|
+
if (segmentAttributes.duration) {
|
|
1004
|
+
const {
|
|
1005
|
+
duration,
|
|
1006
|
+
timescale = 1
|
|
1007
|
+
} = segmentAttributes;
|
|
1008
|
+
segmentAttributes.duration = duration / timescale;
|
|
1009
|
+
} else if (segments.length) {
|
|
1010
|
+
segmentAttributes.duration = segments.reduce((max, segment) => {
|
|
1011
|
+
return Math.max(max, Math.ceil(segment.duration));
|
|
1012
|
+
}, 0);
|
|
1013
|
+
} else {
|
|
1014
|
+
segmentAttributes.duration = 0;
|
|
1015
|
+
}
|
|
1016
|
+
segmentsInfo.attributes = segmentAttributes;
|
|
1017
|
+
segmentsInfo.segments = segments;
|
|
1018
|
+
if (segmentInfo.base && segmentAttributes.indexRange) {
|
|
1019
|
+
segmentsInfo.sidx = segments[0];
|
|
1020
|
+
segmentsInfo.segments = [];
|
|
1021
|
+
}
|
|
1022
|
+
return segmentsInfo;
|
|
1023
|
+
};
|
|
1024
|
+
const toPlaylists = (representations) => representations.map(generateSegments);
|
|
1025
|
+
const findChildren = (element, name) => from(element.childNodes).filter(({
|
|
1026
|
+
tagName
|
|
1027
|
+
}) => tagName === name);
|
|
1028
|
+
const getContent = (element) => element.textContent.trim();
|
|
1029
|
+
const parseDivisionValue = (value) => {
|
|
1030
|
+
return parseFloat(value.split("/").reduce((prev, current) => prev / current));
|
|
1031
|
+
};
|
|
1032
|
+
const parseDuration = (str) => {
|
|
1033
|
+
const SECONDS_IN_YEAR = 365 * 24 * 60 * 60;
|
|
1034
|
+
const SECONDS_IN_MONTH = 30 * 24 * 60 * 60;
|
|
1035
|
+
const SECONDS_IN_DAY = 24 * 60 * 60;
|
|
1036
|
+
const SECONDS_IN_HOUR = 60 * 60;
|
|
1037
|
+
const SECONDS_IN_MIN = 60;
|
|
1038
|
+
const durationRegex = /P(?:(\d*)Y)?(?:(\d*)M)?(?:(\d*)D)?(?:T(?:(\d*)H)?(?:(\d*)M)?(?:([\d.]*)S)?)?/;
|
|
1039
|
+
const match = durationRegex.exec(str);
|
|
1040
|
+
if (!match) {
|
|
1041
|
+
return 0;
|
|
1042
|
+
}
|
|
1043
|
+
const [year, month, day, hour, minute, second] = match.slice(1);
|
|
1044
|
+
return parseFloat(year || 0) * SECONDS_IN_YEAR + parseFloat(month || 0) * SECONDS_IN_MONTH + parseFloat(day || 0) * SECONDS_IN_DAY + parseFloat(hour || 0) * SECONDS_IN_HOUR + parseFloat(minute || 0) * SECONDS_IN_MIN + parseFloat(second || 0);
|
|
1045
|
+
};
|
|
1046
|
+
const parseDate = (str) => {
|
|
1047
|
+
const dateRegex = /^\d+-\d+-\d+T\d+:\d+:\d+(\.\d+)?$/;
|
|
1048
|
+
if (dateRegex.test(str)) {
|
|
1049
|
+
str += "Z";
|
|
1050
|
+
}
|
|
1051
|
+
return Date.parse(str);
|
|
1052
|
+
};
|
|
1053
|
+
const parsers = {
|
|
1054
|
+
/**
|
|
1055
|
+
* Specifies the duration of the entire Media Presentation. Format is a duration string
|
|
1056
|
+
* as specified in ISO 8601
|
|
1057
|
+
*
|
|
1058
|
+
* @param {string} value
|
|
1059
|
+
* value of attribute as a string
|
|
1060
|
+
* @return {number}
|
|
1061
|
+
* The duration in seconds
|
|
1062
|
+
*/
|
|
1063
|
+
mediaPresentationDuration(value) {
|
|
1064
|
+
return parseDuration(value);
|
|
1065
|
+
},
|
|
1066
|
+
/**
|
|
1067
|
+
* Specifies the Segment availability start time for all Segments referred to in this
|
|
1068
|
+
* MPD. For a dynamic manifest, it specifies the anchor for the earliest availability
|
|
1069
|
+
* time. Format is a date string as specified in ISO 8601
|
|
1070
|
+
*
|
|
1071
|
+
* @param {string} value
|
|
1072
|
+
* value of attribute as a string
|
|
1073
|
+
* @return {number}
|
|
1074
|
+
* The date as seconds from unix epoch
|
|
1075
|
+
*/
|
|
1076
|
+
availabilityStartTime(value) {
|
|
1077
|
+
return parseDate(value) / 1e3;
|
|
1078
|
+
},
|
|
1079
|
+
/**
|
|
1080
|
+
* Specifies the smallest period between potential changes to the MPD. Format is a
|
|
1081
|
+
* duration string as specified in ISO 8601
|
|
1082
|
+
*
|
|
1083
|
+
* @param {string} value
|
|
1084
|
+
* value of attribute as a string
|
|
1085
|
+
* @return {number}
|
|
1086
|
+
* The duration in seconds
|
|
1087
|
+
*/
|
|
1088
|
+
minimumUpdatePeriod(value) {
|
|
1089
|
+
return parseDuration(value);
|
|
1090
|
+
},
|
|
1091
|
+
/**
|
|
1092
|
+
* Specifies the suggested presentation delay. Format is a
|
|
1093
|
+
* duration string as specified in ISO 8601
|
|
1094
|
+
*
|
|
1095
|
+
* @param {string} value
|
|
1096
|
+
* value of attribute as a string
|
|
1097
|
+
* @return {number}
|
|
1098
|
+
* The duration in seconds
|
|
1099
|
+
*/
|
|
1100
|
+
suggestedPresentationDelay(value) {
|
|
1101
|
+
return parseDuration(value);
|
|
1102
|
+
},
|
|
1103
|
+
/**
|
|
1104
|
+
* specifices the type of mpd. Can be either "static" or "dynamic"
|
|
1105
|
+
*
|
|
1106
|
+
* @param {string} value
|
|
1107
|
+
* value of attribute as a string
|
|
1108
|
+
*
|
|
1109
|
+
* @return {string}
|
|
1110
|
+
* The type as a string
|
|
1111
|
+
*/
|
|
1112
|
+
type(value) {
|
|
1113
|
+
return value;
|
|
1114
|
+
},
|
|
1115
|
+
/**
|
|
1116
|
+
* Specifies the duration of the smallest time shifting buffer for any Representation
|
|
1117
|
+
* in the MPD. Format is a duration string as specified in ISO 8601
|
|
1118
|
+
*
|
|
1119
|
+
* @param {string} value
|
|
1120
|
+
* value of attribute as a string
|
|
1121
|
+
* @return {number}
|
|
1122
|
+
* The duration in seconds
|
|
1123
|
+
*/
|
|
1124
|
+
timeShiftBufferDepth(value) {
|
|
1125
|
+
return parseDuration(value);
|
|
1126
|
+
},
|
|
1127
|
+
/**
|
|
1128
|
+
* Specifies the PeriodStart time of the Period relative to the availabilityStarttime.
|
|
1129
|
+
* Format is a duration string as specified in ISO 8601
|
|
1130
|
+
*
|
|
1131
|
+
* @param {string} value
|
|
1132
|
+
* value of attribute as a string
|
|
1133
|
+
* @return {number}
|
|
1134
|
+
* The duration in seconds
|
|
1135
|
+
*/
|
|
1136
|
+
start(value) {
|
|
1137
|
+
return parseDuration(value);
|
|
1138
|
+
},
|
|
1139
|
+
/**
|
|
1140
|
+
* Specifies the width of the visual presentation
|
|
1141
|
+
*
|
|
1142
|
+
* @param {string} value
|
|
1143
|
+
* value of attribute as a string
|
|
1144
|
+
* @return {number}
|
|
1145
|
+
* The parsed width
|
|
1146
|
+
*/
|
|
1147
|
+
width(value) {
|
|
1148
|
+
return parseInt(value, 10);
|
|
1149
|
+
},
|
|
1150
|
+
/**
|
|
1151
|
+
* Specifies the height of the visual presentation
|
|
1152
|
+
*
|
|
1153
|
+
* @param {string} value
|
|
1154
|
+
* value of attribute as a string
|
|
1155
|
+
* @return {number}
|
|
1156
|
+
* The parsed height
|
|
1157
|
+
*/
|
|
1158
|
+
height(value) {
|
|
1159
|
+
return parseInt(value, 10);
|
|
1160
|
+
},
|
|
1161
|
+
/**
|
|
1162
|
+
* Specifies the bitrate of the representation
|
|
1163
|
+
*
|
|
1164
|
+
* @param {string} value
|
|
1165
|
+
* value of attribute as a string
|
|
1166
|
+
* @return {number}
|
|
1167
|
+
* The parsed bandwidth
|
|
1168
|
+
*/
|
|
1169
|
+
bandwidth(value) {
|
|
1170
|
+
return parseInt(value, 10);
|
|
1171
|
+
},
|
|
1172
|
+
/**
|
|
1173
|
+
* Specifies the frame rate of the representation
|
|
1174
|
+
*
|
|
1175
|
+
* @param {string} value
|
|
1176
|
+
* value of attribute as a string
|
|
1177
|
+
* @return {number}
|
|
1178
|
+
* The parsed frame rate
|
|
1179
|
+
*/
|
|
1180
|
+
frameRate(value) {
|
|
1181
|
+
return parseDivisionValue(value);
|
|
1182
|
+
},
|
|
1183
|
+
/**
|
|
1184
|
+
* Specifies the number of the first Media Segment in this Representation in the Period
|
|
1185
|
+
*
|
|
1186
|
+
* @param {string} value
|
|
1187
|
+
* value of attribute as a string
|
|
1188
|
+
* @return {number}
|
|
1189
|
+
* The parsed number
|
|
1190
|
+
*/
|
|
1191
|
+
startNumber(value) {
|
|
1192
|
+
return parseInt(value, 10);
|
|
1193
|
+
},
|
|
1194
|
+
/**
|
|
1195
|
+
* Specifies the timescale in units per seconds
|
|
1196
|
+
*
|
|
1197
|
+
* @param {string} value
|
|
1198
|
+
* value of attribute as a string
|
|
1199
|
+
* @return {number}
|
|
1200
|
+
* The parsed timescale
|
|
1201
|
+
*/
|
|
1202
|
+
timescale(value) {
|
|
1203
|
+
return parseInt(value, 10);
|
|
1204
|
+
},
|
|
1205
|
+
/**
|
|
1206
|
+
* Specifies the presentationTimeOffset.
|
|
1207
|
+
*
|
|
1208
|
+
* @param {string} value
|
|
1209
|
+
* value of the attribute as a string
|
|
1210
|
+
*
|
|
1211
|
+
* @return {number}
|
|
1212
|
+
* The parsed presentationTimeOffset
|
|
1213
|
+
*/
|
|
1214
|
+
presentationTimeOffset(value) {
|
|
1215
|
+
return parseInt(value, 10);
|
|
1216
|
+
},
|
|
1217
|
+
/**
|
|
1218
|
+
* Specifies the constant approximate Segment duration
|
|
1219
|
+
* NOTE: The <Period> element also contains an @duration attribute. This duration
|
|
1220
|
+
* specifies the duration of the Period. This attribute is currently not
|
|
1221
|
+
* supported by the rest of the parser, however we still check for it to prevent
|
|
1222
|
+
* errors.
|
|
1223
|
+
*
|
|
1224
|
+
* @param {string} value
|
|
1225
|
+
* value of attribute as a string
|
|
1226
|
+
* @return {number}
|
|
1227
|
+
* The parsed duration
|
|
1228
|
+
*/
|
|
1229
|
+
duration(value) {
|
|
1230
|
+
const parsedValue = parseInt(value, 10);
|
|
1231
|
+
if (isNaN(parsedValue)) {
|
|
1232
|
+
return parseDuration(value);
|
|
1233
|
+
}
|
|
1234
|
+
return parsedValue;
|
|
1235
|
+
},
|
|
1236
|
+
/**
|
|
1237
|
+
* Specifies the Segment duration, in units of the value of the @timescale.
|
|
1238
|
+
*
|
|
1239
|
+
* @param {string} value
|
|
1240
|
+
* value of attribute as a string
|
|
1241
|
+
* @return {number}
|
|
1242
|
+
* The parsed duration
|
|
1243
|
+
*/
|
|
1244
|
+
d(value) {
|
|
1245
|
+
return parseInt(value, 10);
|
|
1246
|
+
},
|
|
1247
|
+
/**
|
|
1248
|
+
* Specifies the MPD start time, in @timescale units, the first Segment in the series
|
|
1249
|
+
* starts relative to the beginning of the Period
|
|
1250
|
+
*
|
|
1251
|
+
* @param {string} value
|
|
1252
|
+
* value of attribute as a string
|
|
1253
|
+
* @return {number}
|
|
1254
|
+
* The parsed time
|
|
1255
|
+
*/
|
|
1256
|
+
t(value) {
|
|
1257
|
+
return parseInt(value, 10);
|
|
1258
|
+
},
|
|
1259
|
+
/**
|
|
1260
|
+
* Specifies the repeat count of the number of following contiguous Segments with the
|
|
1261
|
+
* same duration expressed by the value of @d
|
|
1262
|
+
*
|
|
1263
|
+
* @param {string} value
|
|
1264
|
+
* value of attribute as a string
|
|
1265
|
+
* @return {number}
|
|
1266
|
+
* The parsed number
|
|
1267
|
+
*/
|
|
1268
|
+
r(value) {
|
|
1269
|
+
return parseInt(value, 10);
|
|
1270
|
+
},
|
|
1271
|
+
/**
|
|
1272
|
+
* Specifies the presentationTime.
|
|
1273
|
+
*
|
|
1274
|
+
* @param {string} value
|
|
1275
|
+
* value of the attribute as a string
|
|
1276
|
+
*
|
|
1277
|
+
* @return {number}
|
|
1278
|
+
* The parsed presentationTime
|
|
1279
|
+
*/
|
|
1280
|
+
presentationTime(value) {
|
|
1281
|
+
return parseInt(value, 10);
|
|
1282
|
+
},
|
|
1283
|
+
/**
|
|
1284
|
+
* Default parser for all other attributes. Acts as a no-op and just returns the value
|
|
1285
|
+
* as a string
|
|
1286
|
+
*
|
|
1287
|
+
* @param {string} value
|
|
1288
|
+
* value of attribute as a string
|
|
1289
|
+
* @return {string}
|
|
1290
|
+
* Unparsed value
|
|
1291
|
+
*/
|
|
1292
|
+
DEFAULT(value) {
|
|
1293
|
+
return value;
|
|
1294
|
+
}
|
|
1295
|
+
};
|
|
1296
|
+
const parseAttributes = (el) => {
|
|
1297
|
+
if (!(el && el.attributes)) {
|
|
1298
|
+
return {};
|
|
1299
|
+
}
|
|
1300
|
+
return from(el.attributes).reduce((a, e) => {
|
|
1301
|
+
const parseFn = parsers[e.name] || parsers.DEFAULT;
|
|
1302
|
+
a[e.name] = parseFn(e.value);
|
|
1303
|
+
return a;
|
|
1304
|
+
}, {});
|
|
1305
|
+
};
|
|
1306
|
+
const keySystemsMap = {
|
|
1307
|
+
"urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b": "org.w3.clearkey",
|
|
1308
|
+
"urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed": "com.widevine.alpha",
|
|
1309
|
+
"urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95": "com.microsoft.playready",
|
|
1310
|
+
"urn:uuid:f239e769-efa3-4850-9c16-a903c6932efb": "com.adobe.primetime",
|
|
1311
|
+
// ISO_IEC 23009-1_2022 5.8.5.2.2 The mp4 Protection Scheme
|
|
1312
|
+
"urn:mpeg:dash:mp4protection:2011": "mp4protection"
|
|
1313
|
+
};
|
|
1314
|
+
const buildBaseUrls = (references, baseUrlElements) => {
|
|
1315
|
+
if (!baseUrlElements.length) {
|
|
1316
|
+
return references;
|
|
1317
|
+
}
|
|
1318
|
+
return flatten(references.map(function(reference) {
|
|
1319
|
+
return baseUrlElements.map(function(baseUrlElement) {
|
|
1320
|
+
const initialBaseUrl = getContent(baseUrlElement);
|
|
1321
|
+
const resolvedBaseUrl = resolveUrl(reference.baseUrl, initialBaseUrl);
|
|
1322
|
+
const finalBaseUrl = merge(parseAttributes(baseUrlElement), {
|
|
1323
|
+
baseUrl: resolvedBaseUrl
|
|
1324
|
+
});
|
|
1325
|
+
if (resolvedBaseUrl !== initialBaseUrl && !finalBaseUrl.serviceLocation && reference.serviceLocation) {
|
|
1326
|
+
finalBaseUrl.serviceLocation = reference.serviceLocation;
|
|
1327
|
+
}
|
|
1328
|
+
return finalBaseUrl;
|
|
1329
|
+
});
|
|
1330
|
+
}));
|
|
1331
|
+
};
|
|
1332
|
+
const getSegmentInformation = (adaptationSet) => {
|
|
1333
|
+
const segmentTemplate = findChildren(adaptationSet, "SegmentTemplate")[0];
|
|
1334
|
+
const segmentList = findChildren(adaptationSet, "SegmentList")[0];
|
|
1335
|
+
const segmentUrls = segmentList && findChildren(segmentList, "SegmentURL").map((s) => merge({
|
|
1336
|
+
tag: "SegmentURL"
|
|
1337
|
+
}, parseAttributes(s)));
|
|
1338
|
+
const segmentBase = findChildren(adaptationSet, "SegmentBase")[0];
|
|
1339
|
+
const segmentTimelineParentNode = segmentList || segmentTemplate;
|
|
1340
|
+
const segmentTimeline = segmentTimelineParentNode && findChildren(segmentTimelineParentNode, "SegmentTimeline")[0];
|
|
1341
|
+
const segmentInitializationParentNode = segmentList || segmentBase || segmentTemplate;
|
|
1342
|
+
const segmentInitialization = segmentInitializationParentNode && findChildren(segmentInitializationParentNode, "Initialization")[0];
|
|
1343
|
+
const template = segmentTemplate && parseAttributes(segmentTemplate);
|
|
1344
|
+
if (template && segmentInitialization) {
|
|
1345
|
+
template.initialization = segmentInitialization && parseAttributes(segmentInitialization);
|
|
1346
|
+
} else if (template && template.initialization) {
|
|
1347
|
+
template.initialization = {
|
|
1348
|
+
sourceURL: template.initialization
|
|
1349
|
+
};
|
|
1350
|
+
}
|
|
1351
|
+
const segmentInfo = {
|
|
1352
|
+
template,
|
|
1353
|
+
segmentTimeline: segmentTimeline && findChildren(segmentTimeline, "S").map((s) => parseAttributes(s)),
|
|
1354
|
+
list: segmentList && merge(parseAttributes(segmentList), {
|
|
1355
|
+
segmentUrls,
|
|
1356
|
+
initialization: parseAttributes(segmentInitialization)
|
|
1357
|
+
}),
|
|
1358
|
+
base: segmentBase && merge(parseAttributes(segmentBase), {
|
|
1359
|
+
initialization: parseAttributes(segmentInitialization)
|
|
1360
|
+
})
|
|
1361
|
+
};
|
|
1362
|
+
Object.keys(segmentInfo).forEach((key) => {
|
|
1363
|
+
if (!segmentInfo[key]) {
|
|
1364
|
+
delete segmentInfo[key];
|
|
1365
|
+
}
|
|
1366
|
+
});
|
|
1367
|
+
return segmentInfo;
|
|
1368
|
+
};
|
|
1369
|
+
const inheritBaseUrls = (adaptationSetAttributes, adaptationSetBaseUrls, adaptationSetSegmentInfo) => (representation) => {
|
|
1370
|
+
const repBaseUrlElements = findChildren(representation, "BaseURL");
|
|
1371
|
+
const repBaseUrls = buildBaseUrls(adaptationSetBaseUrls, repBaseUrlElements);
|
|
1372
|
+
const attributes = merge(adaptationSetAttributes, parseAttributes(representation));
|
|
1373
|
+
const representationSegmentInfo = getSegmentInformation(representation);
|
|
1374
|
+
return repBaseUrls.map((baseUrl) => {
|
|
1375
|
+
return {
|
|
1376
|
+
segmentInfo: merge(adaptationSetSegmentInfo, representationSegmentInfo),
|
|
1377
|
+
attributes: merge(attributes, baseUrl)
|
|
1378
|
+
};
|
|
1379
|
+
});
|
|
1380
|
+
};
|
|
1381
|
+
const generateKeySystemInformation = (contentProtectionNodes) => {
|
|
1382
|
+
return contentProtectionNodes.reduce((acc, node) => {
|
|
1383
|
+
const attributes = parseAttributes(node);
|
|
1384
|
+
if (attributes.schemeIdUri) {
|
|
1385
|
+
attributes.schemeIdUri = attributes.schemeIdUri.toLowerCase();
|
|
1386
|
+
}
|
|
1387
|
+
const keySystem = keySystemsMap[attributes.schemeIdUri];
|
|
1388
|
+
if (keySystem) {
|
|
1389
|
+
acc[keySystem] = {
|
|
1390
|
+
attributes
|
|
1391
|
+
};
|
|
1392
|
+
const psshNode = findChildren(node, "cenc:pssh")[0];
|
|
1393
|
+
if (psshNode) {
|
|
1394
|
+
const pssh = getContent(psshNode);
|
|
1395
|
+
acc[keySystem].pssh = pssh && decodeB64ToUint8Array(pssh);
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
1398
|
+
return acc;
|
|
1399
|
+
}, {});
|
|
1400
|
+
};
|
|
1401
|
+
const parseCaptionServiceMetadata = (service) => {
|
|
1402
|
+
if (service.schemeIdUri === "urn:scte:dash:cc:cea-608:2015") {
|
|
1403
|
+
const values2 = typeof service.value !== "string" ? [] : service.value.split(";");
|
|
1404
|
+
return values2.map((value) => {
|
|
1405
|
+
let channel;
|
|
1406
|
+
let language;
|
|
1407
|
+
language = value;
|
|
1408
|
+
if (/^CC\d=/.test(value)) {
|
|
1409
|
+
[channel, language] = value.split("=");
|
|
1410
|
+
} else if (/^CC\d$/.test(value)) {
|
|
1411
|
+
channel = value;
|
|
1412
|
+
}
|
|
1413
|
+
return {
|
|
1414
|
+
channel,
|
|
1415
|
+
language
|
|
1416
|
+
};
|
|
1417
|
+
});
|
|
1418
|
+
} else if (service.schemeIdUri === "urn:scte:dash:cc:cea-708:2015") {
|
|
1419
|
+
const values2 = typeof service.value !== "string" ? [] : service.value.split(";");
|
|
1420
|
+
return values2.map((value) => {
|
|
1421
|
+
const flags = {
|
|
1422
|
+
// service or channel number 1-63
|
|
1423
|
+
"channel": void 0,
|
|
1424
|
+
// language is a 3ALPHA per ISO 639.2/B
|
|
1425
|
+
// field is required
|
|
1426
|
+
"language": void 0,
|
|
1427
|
+
// BIT 1/0 or ?
|
|
1428
|
+
// default value is 1, meaning 16:9 aspect ratio, 0 is 4:3, ? is unknown
|
|
1429
|
+
"aspectRatio": 1,
|
|
1430
|
+
// BIT 1/0
|
|
1431
|
+
// easy reader flag indicated the text is tailed to the needs of beginning readers
|
|
1432
|
+
// default 0, or off
|
|
1433
|
+
"easyReader": 0,
|
|
1434
|
+
// BIT 1/0
|
|
1435
|
+
// If 3d metadata is present (CEA-708.1) then 1
|
|
1436
|
+
// default 0
|
|
1437
|
+
"3D": 0
|
|
1438
|
+
};
|
|
1439
|
+
if (/=/.test(value)) {
|
|
1440
|
+
const [channel, opts = ""] = value.split("=");
|
|
1441
|
+
flags.channel = channel;
|
|
1442
|
+
flags.language = value;
|
|
1443
|
+
opts.split(",").forEach((opt) => {
|
|
1444
|
+
const [name, val] = opt.split(":");
|
|
1445
|
+
if (name === "lang") {
|
|
1446
|
+
flags.language = val;
|
|
1447
|
+
} else if (name === "er") {
|
|
1448
|
+
flags.easyReader = Number(val);
|
|
1449
|
+
} else if (name === "war") {
|
|
1450
|
+
flags.aspectRatio = Number(val);
|
|
1451
|
+
} else if (name === "3D") {
|
|
1452
|
+
flags["3D"] = Number(val);
|
|
1453
|
+
}
|
|
1454
|
+
});
|
|
1455
|
+
} else {
|
|
1456
|
+
flags.language = value;
|
|
1457
|
+
}
|
|
1458
|
+
if (flags.channel) {
|
|
1459
|
+
flags.channel = "SERVICE" + flags.channel;
|
|
1460
|
+
}
|
|
1461
|
+
return flags;
|
|
1462
|
+
});
|
|
1463
|
+
}
|
|
1464
|
+
};
|
|
1465
|
+
const toEventStream = (period) => {
|
|
1466
|
+
return flatten(findChildren(period.node, "EventStream").map((eventStream) => {
|
|
1467
|
+
const eventStreamAttributes = parseAttributes(eventStream);
|
|
1468
|
+
const schemeIdUri = eventStreamAttributes.schemeIdUri;
|
|
1469
|
+
return findChildren(eventStream, "Event").map((event) => {
|
|
1470
|
+
const eventAttributes = parseAttributes(event);
|
|
1471
|
+
const presentationTime = eventAttributes.presentationTime || 0;
|
|
1472
|
+
const timescale = eventStreamAttributes.timescale || 1;
|
|
1473
|
+
const duration = eventAttributes.duration || 0;
|
|
1474
|
+
const start = presentationTime / timescale + period.attributes.start;
|
|
1475
|
+
return {
|
|
1476
|
+
schemeIdUri,
|
|
1477
|
+
value: eventStreamAttributes.value,
|
|
1478
|
+
id: eventAttributes.id,
|
|
1479
|
+
start,
|
|
1480
|
+
end: start + duration / timescale,
|
|
1481
|
+
messageData: getContent(event) || eventAttributes.messageData,
|
|
1482
|
+
contentEncoding: eventStreamAttributes.contentEncoding,
|
|
1483
|
+
presentationTimeOffset: eventStreamAttributes.presentationTimeOffset || 0
|
|
1484
|
+
};
|
|
1485
|
+
});
|
|
1486
|
+
}));
|
|
1487
|
+
};
|
|
1488
|
+
const toRepresentations = (periodAttributes, periodBaseUrls, periodSegmentInfo) => (adaptationSet) => {
|
|
1489
|
+
const adaptationSetAttributes = parseAttributes(adaptationSet);
|
|
1490
|
+
const adaptationSetBaseUrls = buildBaseUrls(periodBaseUrls, findChildren(adaptationSet, "BaseURL"));
|
|
1491
|
+
const role = findChildren(adaptationSet, "Role")[0];
|
|
1492
|
+
const roleAttributes = {
|
|
1493
|
+
role: parseAttributes(role)
|
|
1494
|
+
};
|
|
1495
|
+
let attrs = merge(periodAttributes, adaptationSetAttributes, roleAttributes);
|
|
1496
|
+
const accessibility = findChildren(adaptationSet, "Accessibility")[0];
|
|
1497
|
+
const captionServices = parseCaptionServiceMetadata(parseAttributes(accessibility));
|
|
1498
|
+
if (captionServices) {
|
|
1499
|
+
attrs = merge(attrs, {
|
|
1500
|
+
captionServices
|
|
1501
|
+
});
|
|
1502
|
+
}
|
|
1503
|
+
const label = findChildren(adaptationSet, "Label")[0];
|
|
1504
|
+
if (label && label.childNodes.length) {
|
|
1505
|
+
const labelVal = label.childNodes[0].nodeValue.trim();
|
|
1506
|
+
attrs = merge(attrs, {
|
|
1507
|
+
label: labelVal
|
|
1508
|
+
});
|
|
1509
|
+
}
|
|
1510
|
+
const contentProtection = generateKeySystemInformation(findChildren(adaptationSet, "ContentProtection"));
|
|
1511
|
+
if (Object.keys(contentProtection).length) {
|
|
1512
|
+
attrs = merge(attrs, {
|
|
1513
|
+
contentProtection
|
|
1514
|
+
});
|
|
1515
|
+
}
|
|
1516
|
+
const segmentInfo = getSegmentInformation(adaptationSet);
|
|
1517
|
+
const representations = findChildren(adaptationSet, "Representation");
|
|
1518
|
+
const adaptationSetSegmentInfo = merge(periodSegmentInfo, segmentInfo);
|
|
1519
|
+
return flatten(representations.map(inheritBaseUrls(attrs, adaptationSetBaseUrls, adaptationSetSegmentInfo)));
|
|
1520
|
+
};
|
|
1521
|
+
const toAdaptationSets = (mpdAttributes, mpdBaseUrls) => (period, index) => {
|
|
1522
|
+
const periodBaseUrls = buildBaseUrls(mpdBaseUrls, findChildren(period.node, "BaseURL"));
|
|
1523
|
+
const periodAttributes = merge(mpdAttributes, {
|
|
1524
|
+
periodStart: period.attributes.start
|
|
1525
|
+
});
|
|
1526
|
+
if (typeof period.attributes.duration === "number") {
|
|
1527
|
+
periodAttributes.periodDuration = period.attributes.duration;
|
|
1528
|
+
}
|
|
1529
|
+
const adaptationSets = findChildren(period.node, "AdaptationSet");
|
|
1530
|
+
const periodSegmentInfo = getSegmentInformation(period.node);
|
|
1531
|
+
return flatten(adaptationSets.map(toRepresentations(periodAttributes, periodBaseUrls, periodSegmentInfo)));
|
|
1532
|
+
};
|
|
1533
|
+
const generateContentSteeringInformation = (contentSteeringNodes, eventHandler) => {
|
|
1534
|
+
if (contentSteeringNodes.length > 1) {
|
|
1535
|
+
eventHandler({
|
|
1536
|
+
type: "warn",
|
|
1537
|
+
message: "The MPD manifest should contain no more than one ContentSteering tag"
|
|
1538
|
+
});
|
|
1539
|
+
}
|
|
1540
|
+
if (!contentSteeringNodes.length) {
|
|
1541
|
+
return null;
|
|
1542
|
+
}
|
|
1543
|
+
const infoFromContentSteeringTag = merge({
|
|
1544
|
+
serverURL: getContent(contentSteeringNodes[0])
|
|
1545
|
+
}, parseAttributes(contentSteeringNodes[0]));
|
|
1546
|
+
infoFromContentSteeringTag.queryBeforeStart = infoFromContentSteeringTag.queryBeforeStart === "true";
|
|
1547
|
+
return infoFromContentSteeringTag;
|
|
1548
|
+
};
|
|
1549
|
+
const getPeriodStart = ({
|
|
1550
|
+
attributes,
|
|
1551
|
+
priorPeriodAttributes,
|
|
1552
|
+
mpdType
|
|
1553
|
+
}) => {
|
|
1554
|
+
if (typeof attributes.start === "number") {
|
|
1555
|
+
return attributes.start;
|
|
1556
|
+
}
|
|
1557
|
+
if (priorPeriodAttributes && typeof priorPeriodAttributes.start === "number" && typeof priorPeriodAttributes.duration === "number") {
|
|
1558
|
+
return priorPeriodAttributes.start + priorPeriodAttributes.duration;
|
|
1559
|
+
}
|
|
1560
|
+
if (!priorPeriodAttributes && mpdType === "static") {
|
|
1561
|
+
return 0;
|
|
1562
|
+
}
|
|
1563
|
+
return null;
|
|
1564
|
+
};
|
|
1565
|
+
const inheritAttributes = (mpd, options = {}) => {
|
|
1566
|
+
const {
|
|
1567
|
+
manifestUri = "",
|
|
1568
|
+
NOW = Date.now(),
|
|
1569
|
+
clientOffset = 0,
|
|
1570
|
+
// TODO: For now, we are expecting an eventHandler callback function
|
|
1571
|
+
// to be passed into the mpd parser as an option.
|
|
1572
|
+
// In the future, we should enable stream parsing by using the Stream class from vhs-utils.
|
|
1573
|
+
// This will support new features including a standardized event handler.
|
|
1574
|
+
// See the m3u8 parser for examples of how stream parsing is currently used for HLS parsing.
|
|
1575
|
+
// https://github.com/videojs/vhs-utils/blob/88d6e10c631e57a5af02c5a62bc7376cd456b4f5/src/stream.js#L9
|
|
1576
|
+
eventHandler = function() {
|
|
1577
|
+
}
|
|
1578
|
+
} = options;
|
|
1579
|
+
const periodNodes = findChildren(mpd, "Period");
|
|
1580
|
+
if (!periodNodes.length) {
|
|
1581
|
+
throw new Error(errors.INVALID_NUMBER_OF_PERIOD);
|
|
1582
|
+
}
|
|
1583
|
+
const locations = findChildren(mpd, "Location");
|
|
1584
|
+
const mpdAttributes = parseAttributes(mpd);
|
|
1585
|
+
const mpdBaseUrls = buildBaseUrls([{
|
|
1586
|
+
baseUrl: manifestUri
|
|
1587
|
+
}], findChildren(mpd, "BaseURL"));
|
|
1588
|
+
const contentSteeringNodes = findChildren(mpd, "ContentSteering");
|
|
1589
|
+
mpdAttributes.type = mpdAttributes.type || "static";
|
|
1590
|
+
mpdAttributes.sourceDuration = mpdAttributes.mediaPresentationDuration || 0;
|
|
1591
|
+
mpdAttributes.NOW = NOW;
|
|
1592
|
+
mpdAttributes.clientOffset = clientOffset;
|
|
1593
|
+
if (locations.length) {
|
|
1594
|
+
mpdAttributes.locations = locations.map(getContent);
|
|
1595
|
+
}
|
|
1596
|
+
const periods = [];
|
|
1597
|
+
periodNodes.forEach((node, index) => {
|
|
1598
|
+
const attributes = parseAttributes(node);
|
|
1599
|
+
const priorPeriod = periods[index - 1];
|
|
1600
|
+
attributes.start = getPeriodStart({
|
|
1601
|
+
attributes,
|
|
1602
|
+
priorPeriodAttributes: priorPeriod ? priorPeriod.attributes : null,
|
|
1603
|
+
mpdType: mpdAttributes.type
|
|
1604
|
+
});
|
|
1605
|
+
periods.push({
|
|
1606
|
+
node,
|
|
1607
|
+
attributes
|
|
1608
|
+
});
|
|
1609
|
+
});
|
|
1610
|
+
return {
|
|
1611
|
+
locations: mpdAttributes.locations,
|
|
1612
|
+
contentSteeringInfo: generateContentSteeringInformation(contentSteeringNodes, eventHandler),
|
|
1613
|
+
// TODO: There are occurences where this `representationInfo` array contains undesired
|
|
1614
|
+
// duplicates. This generally occurs when there are multiple BaseURL nodes that are
|
|
1615
|
+
// direct children of the MPD node. When we attempt to resolve URLs from a combination of the
|
|
1616
|
+
// parent BaseURL and a child BaseURL, and the value does not resolve,
|
|
1617
|
+
// we end up returning the child BaseURL multiple times.
|
|
1618
|
+
// We need to determine a way to remove these duplicates in a safe way.
|
|
1619
|
+
// See: https://github.com/videojs/mpd-parser/pull/17#discussion_r162750527
|
|
1620
|
+
representationInfo: flatten(periods.map(toAdaptationSets(mpdAttributes, mpdBaseUrls))),
|
|
1621
|
+
eventStream: flatten(periods.map(toEventStream))
|
|
1622
|
+
};
|
|
1623
|
+
};
|
|
1624
|
+
const stringToMpdXml = (manifestString) => {
|
|
1625
|
+
if (manifestString === "") {
|
|
1626
|
+
throw new Error(errors.DASH_EMPTY_MANIFEST);
|
|
1627
|
+
}
|
|
1628
|
+
const parser = new libExports.DOMParser();
|
|
1629
|
+
let xml;
|
|
1630
|
+
let mpd;
|
|
1631
|
+
try {
|
|
1632
|
+
xml = parser.parseFromString(manifestString, "application/xml");
|
|
1633
|
+
mpd = xml && xml.documentElement.tagName === "MPD" ? xml.documentElement : null;
|
|
1634
|
+
} catch (e) {
|
|
1635
|
+
}
|
|
1636
|
+
if (!mpd || mpd && mpd.getElementsByTagName("parsererror").length > 0) {
|
|
1637
|
+
throw new Error(errors.DASH_INVALID_XML);
|
|
1638
|
+
}
|
|
1639
|
+
return mpd;
|
|
1640
|
+
};
|
|
1641
|
+
const parseUTCTimingScheme = (mpd) => {
|
|
1642
|
+
const UTCTimingNode = findChildren(mpd, "UTCTiming")[0];
|
|
1643
|
+
if (!UTCTimingNode) {
|
|
1644
|
+
return null;
|
|
1645
|
+
}
|
|
1646
|
+
const attributes = parseAttributes(UTCTimingNode);
|
|
1647
|
+
switch (attributes.schemeIdUri) {
|
|
1648
|
+
case "urn:mpeg:dash:utc:http-head:2014":
|
|
1649
|
+
case "urn:mpeg:dash:utc:http-head:2012":
|
|
1650
|
+
attributes.method = "HEAD";
|
|
1651
|
+
break;
|
|
1652
|
+
case "urn:mpeg:dash:utc:http-xsdate:2014":
|
|
1653
|
+
case "urn:mpeg:dash:utc:http-iso:2014":
|
|
1654
|
+
case "urn:mpeg:dash:utc:http-xsdate:2012":
|
|
1655
|
+
case "urn:mpeg:dash:utc:http-iso:2012":
|
|
1656
|
+
attributes.method = "GET";
|
|
1657
|
+
break;
|
|
1658
|
+
case "urn:mpeg:dash:utc:direct:2014":
|
|
1659
|
+
case "urn:mpeg:dash:utc:direct:2012":
|
|
1660
|
+
attributes.method = "DIRECT";
|
|
1661
|
+
attributes.value = Date.parse(attributes.value);
|
|
1662
|
+
break;
|
|
1663
|
+
case "urn:mpeg:dash:utc:http-ntp:2014":
|
|
1664
|
+
case "urn:mpeg:dash:utc:ntp:2014":
|
|
1665
|
+
case "urn:mpeg:dash:utc:sntp:2014":
|
|
1666
|
+
default:
|
|
1667
|
+
throw new Error(errors.UNSUPPORTED_UTC_TIMING_SCHEME);
|
|
1668
|
+
}
|
|
1669
|
+
return attributes;
|
|
1670
|
+
};
|
|
1671
|
+
const parse = (manifestString, options = {}) => {
|
|
1672
|
+
const parsedManifestInfo = inheritAttributes(stringToMpdXml(manifestString), options);
|
|
1673
|
+
const playlists = toPlaylists(parsedManifestInfo.representationInfo);
|
|
1674
|
+
return toM3u8({
|
|
1675
|
+
dashPlaylists: playlists,
|
|
1676
|
+
locations: parsedManifestInfo.locations,
|
|
1677
|
+
contentSteering: parsedManifestInfo.contentSteeringInfo,
|
|
1678
|
+
sidxMapping: options.sidxMapping,
|
|
1679
|
+
previousManifest: options.previousManifest,
|
|
1680
|
+
eventStream: parsedManifestInfo.eventStream
|
|
1681
|
+
});
|
|
1682
|
+
};
|
|
1683
|
+
const parseUTCTiming = (manifestString) => parseUTCTimingScheme(stringToMpdXml(manifestString));
|
|
1684
|
+
export {
|
|
1685
|
+
addSidxSegmentsToPlaylist$1 as addSidxSegmentsToPlaylist,
|
|
1686
|
+
generateSidxKey,
|
|
1687
|
+
inheritAttributes,
|
|
1688
|
+
parse,
|
|
1689
|
+
parseUTCTiming,
|
|
1690
|
+
stringToMpdXml,
|
|
1691
|
+
toM3u8,
|
|
1692
|
+
toPlaylists
|
|
1693
|
+
};
|