├── Document
├── qplayer2-core
│ └── html
│ │ ├── images
│ │ ├── anchor-copy-button.svg
│ │ ├── arrow_down.svg
│ │ ├── copy-icon.svg
│ │ ├── copy-successful-icon.svg
│ │ ├── footer-go-to-link.svg
│ │ ├── go-to-top-icon.svg
│ │ ├── logo-icon.svg
│ │ └── theme-toggle.svg
│ │ ├── index.html
│ │ ├── navigation.html
│ │ ├── qplayer2-core
│ │ ├── com.qiniu.qmedia.component.player
│ │ │ ├── -q-authentication-error-type
│ │ │ │ ├── -companion
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── value-of.html
│ │ │ │ ├── -n-o-n-e
│ │ │ │ │ └── index.html
│ │ │ │ ├── -n-o_-a-p-m_-a-u-t-h
│ │ │ │ │ └── index.html
│ │ │ │ ├── -n-o_-b-a-s-e_-a-u-t-h
│ │ │ │ │ └── index.html
│ │ │ │ ├── -n-o_-b-l-i-n-d_-a-u-t-h
│ │ │ │ │ └── index.html
│ │ │ │ ├── -n-o_-s-e-i_-a-u-t-h
│ │ │ │ │ └── index.html
│ │ │ │ ├── -n-o_-s-r-t_-a-u-t-h
│ │ │ │ │ └── index.html
│ │ │ │ ├── -n-o_-v-r_-a-u-t-h
│ │ │ │ │ └── index.html
│ │ │ │ ├── code.html
│ │ │ │ └── index.html
│ │ │ ├── -q-i-media-item-command-not-allow-listener
│ │ │ │ ├── index.html
│ │ │ │ └── on-command-not-allow.html
│ │ │ ├── -q-i-media-item-control-handler
│ │ │ │ ├── index.html
│ │ │ │ ├── pause.html
│ │ │ │ ├── resume.html
│ │ │ │ ├── start.html
│ │ │ │ └── stop.html
│ │ │ ├── -q-i-media-item-log-handler
│ │ │ │ ├── index.html
│ │ │ │ ├── log.html
│ │ │ │ └── set-log-level.html
│ │ │ ├── -q-i-media-item-state-change-listener-collection
│ │ │ │ ├── add-media-item-state-change-listener.html
│ │ │ │ ├── index.html
│ │ │ │ ├── remove-all-play-media-state-change-listener.html
│ │ │ │ └── remove-play-media-state-change-listener.html
│ │ │ ├── -q-i-media-item-state-change-listener
│ │ │ │ ├── index.html
│ │ │ │ └── on-state-changed.html
│ │ │ ├── -q-i-player-audio-data-listener
│ │ │ │ ├── -q-channel-layout
│ │ │ │ │ ├── -companion
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── value-of.html
│ │ │ │ │ ├── -l-a-y-o-u-t_-s-t-e-r-e-o
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── -n-o-n-e
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── value.html
│ │ │ │ ├── -q-sample-format
│ │ │ │ │ ├── -companion
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── value-of.html
│ │ │ │ │ ├── -n-o-n-e
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── -s-i-g-n_-i-n-t_16
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── value.html
│ │ │ │ ├── index.html
│ │ │ │ └── on-audio-data.html
│ │ │ ├── -q-i-player-audio-listener
│ │ │ │ ├── index.html
│ │ │ │ └── on-mute-changed.html
│ │ │ ├── -q-i-player-authentication-listener
│ │ │ │ ├── index.html
│ │ │ │ ├── on_authentication_failed.html
│ │ │ │ └── on_authentication_success.html
│ │ │ ├── -q-i-player-bite-rate-listener
│ │ │ │ ├── index.html
│ │ │ │ └── on-bite-rate-changed.html
│ │ │ ├── -q-i-player-buffering-listener
│ │ │ │ ├── index.html
│ │ │ │ ├── on-buffering-end.html
│ │ │ │ └── on-buffering-start.html
│ │ │ ├── -q-i-player-command-not-allow-listener
│ │ │ │ ├── index.html
│ │ │ │ └── on-command-not-allow.html
│ │ │ ├── -q-i-player-control-handler
│ │ │ │ ├── force-authentication-from-network.html
│ │ │ │ ├── index.html
│ │ │ │ ├── init.html
│ │ │ │ ├── pause-render.html
│ │ │ │ ├── play-media-item.html
│ │ │ │ ├── play-media-model.html
│ │ │ │ ├── release.html
│ │ │ │ ├── resume-render.html
│ │ │ │ ├── seek.html
│ │ │ │ ├── set-audio-data-callback-enable.html
│ │ │ │ ├── set-decode-type.html
│ │ │ │ ├── set-log-level.html
│ │ │ │ ├── set-mute.html
│ │ │ │ ├── set-s-e-i-enable.html
│ │ │ │ ├── set-seek-mode.html
│ │ │ │ ├── set-speed.html
│ │ │ │ ├── set-start-action.html
│ │ │ │ ├── set-subtitle-enable.html
│ │ │ │ ├── set-subtitle.html
│ │ │ │ ├── set-video-data-callback-enable.html
│ │ │ │ ├── set-video-data-callback-type.html
│ │ │ │ ├── shoot-video.html
│ │ │ │ ├── stop.html
│ │ │ │ └── switch-quality.html
│ │ │ ├── -q-i-player-download-listener
│ │ │ │ ├── index.html
│ │ │ │ └── on-download-changed.html
│ │ │ ├── -q-i-player-f-p-s-listener
│ │ │ │ ├── index.html
│ │ │ │ └── on-f-p-s-changed.html
│ │ │ ├── -q-i-player-format-listener
│ │ │ │ ├── index.html
│ │ │ │ └── on-format-not-support.html
│ │ │ ├── -q-i-player-log-handler
│ │ │ │ └── index.html
│ │ │ ├── -q-i-player-media-network-listener
│ │ │ │ ├── -open-error
│ │ │ │ │ ├── -companion
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── value-of.html
│ │ │ │ │ ├── -f-o-r-m-a-t_-i-n-v-a-l-i-d
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── -i-n-t-e-r-r-u-p-t
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── -i-o-e-r-r-o-r
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── -n-o-n-e
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── -u-n-k-o-w-n
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── -u-r-l_-i-n-v-a-l-i-d
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── error.html
│ │ │ │ │ └── index.html
│ │ │ │ ├── index.html
│ │ │ │ ├── on-open-failed.html
│ │ │ │ ├── on-reconnect-end.html
│ │ │ │ └── on-reconnect-start.html
│ │ │ ├── -q-i-player-progress-listener
│ │ │ │ ├── index.html
│ │ │ │ └── on-progress-changed.html
│ │ │ ├── -q-i-player-quality-listener
│ │ │ │ ├── index.html
│ │ │ │ ├── on-quality-switch-canceled.html
│ │ │ │ ├── on-quality-switch-complete.html
│ │ │ │ ├── on-quality-switch-failed.html
│ │ │ │ ├── on-quality-switch-retry-later.html
│ │ │ │ └── on-quality-switch-start.html
│ │ │ ├── -q-i-player-render-handler
│ │ │ │ ├── index.html
│ │ │ │ ├── set-blind-type.html
│ │ │ │ ├── set-mirror-type.html
│ │ │ │ ├── set-panorama-view-rotate.html
│ │ │ │ ├── set-panorama-view-scale.html
│ │ │ │ ├── set-render-ratio.html
│ │ │ │ ├── set-rotation.html
│ │ │ │ ├── set-scale.html
│ │ │ │ ├── set-surface.html
│ │ │ │ └── synch-surface-size.html
│ │ │ ├── -q-i-player-render-listener
│ │ │ │ ├── index.html
│ │ │ │ └── on-first-frame-rendered.html
│ │ │ ├── -q-i-player-s-e-i-data-listener
│ │ │ │ ├── index.html
│ │ │ │ └── on-s-e-i-data.html
│ │ │ ├── -q-i-player-seek-listener
│ │ │ │ ├── index.html
│ │ │ │ ├── on-seek-failed.html
│ │ │ │ └── on-seek-success.html
│ │ │ ├── -q-i-player-shoot-video-listener
│ │ │ │ ├── -shoot-video-type
│ │ │ │ │ ├── -companion
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── value-of.html
│ │ │ │ │ ├── -j-p-e-g
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── -n-o-n-e
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── type.html
│ │ │ │ ├── index.html
│ │ │ │ ├── on-shoot-failed.html
│ │ │ │ └── on-shoot-successful.html
│ │ │ ├── -q-i-player-speed-listener
│ │ │ │ ├── index.html
│ │ │ │ └── on-speed-changed.html
│ │ │ ├── -q-i-player-state-change-listener-collection
│ │ │ │ ├── add-player-state-change-listener.html
│ │ │ │ ├── index.html
│ │ │ │ ├── remove-all-player-state-change-listener.html
│ │ │ │ └── remove-player-state-change-listener.html
│ │ │ ├── -q-i-player-state-change-listener
│ │ │ │ ├── index.html
│ │ │ │ └── on-state-changed.html
│ │ │ ├── -q-i-player-subtitle-listener
│ │ │ │ ├── index.html
│ │ │ │ ├── on_subtitle_close.html
│ │ │ │ ├── on_subtitle_decoded.html
│ │ │ │ ├── on_subtitle_loaded.html
│ │ │ │ ├── on_subtitle_name_change.html
│ │ │ │ ├── on_subtitle_open.html
│ │ │ │ └── on_subtitle_text_change.html
│ │ │ ├── -q-i-player-video-data-listener
│ │ │ │ ├── -q-video-data-type
│ │ │ │ │ ├── -companion
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── value-of.html
│ │ │ │ │ ├── -n-o-n-e
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── -n-v21
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── -r-g-b-a
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── -y-u-v_420-p
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── value.html
│ │ │ │ ├── index.html
│ │ │ │ └── on-video-data.html
│ │ │ ├── -q-i-player-video-decode-listener
│ │ │ │ ├── index.html
│ │ │ │ ├── not-support-codec-format.html
│ │ │ │ ├── on-decode-failed.html
│ │ │ │ └── on-video-decode-by-type.html
│ │ │ ├── -q-i-player-video-frame-size-change-listener
│ │ │ │ ├── index.html
│ │ │ │ └── on-video-frame-size-changed.html
│ │ │ ├── -q-log-level
│ │ │ │ ├── -l-o-g_-d-e-b-u-g
│ │ │ │ │ └── index.html
│ │ │ │ ├── -l-o-g_-e-r-r-o-r
│ │ │ │ │ └── index.html
│ │ │ │ ├── -l-o-g_-i-n-f-o
│ │ │ │ │ └── index.html
│ │ │ │ ├── -l-o-g_-q-u-i-t
│ │ │ │ │ └── index.html
│ │ │ │ ├── -l-o-g_-v-e-r-b-o-s-e
│ │ │ │ │ └── index.html
│ │ │ │ ├── -l-o-g_-w-a-r-n-i-n-g
│ │ │ │ │ └── index.html
│ │ │ │ ├── index.html
│ │ │ │ └── level.html
│ │ │ ├── -q-media-item-context
│ │ │ │ ├── -q-media-item-context.html
│ │ │ │ ├── index.html
│ │ │ │ └── play-media-control-handler.html
│ │ │ ├── -q-media-item-control-handler
│ │ │ │ ├── current-state.html
│ │ │ │ └── index.html
│ │ │ ├── -q-media-item-notify
│ │ │ │ ├── -companion
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── value-of.html
│ │ │ │ ├── -n-o-n-e
│ │ │ │ │ └── index.html
│ │ │ │ ├── -n-o-t-i-f-y_-e-v-e-n-t_-l-o-o-p_-c-o-m-m-o-n-d_-n-o-t_-a-l-l-o-w
│ │ │ │ │ └── index.html
│ │ │ │ ├── -n-o-t-i-f-y_-i-n-p-u-t_-s-t-r-e-a-m_-i-o_-e-r-r-o-r
│ │ │ │ │ └── index.html
│ │ │ │ ├── -n-o-t-i-f-y_-i-n-p-u-t_-s-t-r-e-a-m_-o-p-e-n
│ │ │ │ │ └── index.html
│ │ │ │ ├── -n-o-t-i-f-y_-i-n-p-u-t_-s-t-r-e-a-m_-o-p-e-n_-e-r-r-o-r
│ │ │ │ │ └── index.html
│ │ │ │ ├── index.html
│ │ │ │ └── value.html
│ │ │ ├── -q-media-item-state
│ │ │ │ ├── -companion
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── value-of.html
│ │ │ │ ├── -d-i-s-c-a-r-d
│ │ │ │ │ └── index.html
│ │ │ │ ├── -e-r-r-o-r
│ │ │ │ │ └── index.html
│ │ │ │ ├── -l-o-a-d-i-n-g
│ │ │ │ │ └── index.html
│ │ │ │ ├── -n-o-n-e
│ │ │ │ │ └── index.html
│ │ │ │ ├── -p-a-u-s-e-d
│ │ │ │ │ └── index.html
│ │ │ │ ├── -p-r-e-p-a-r-e
│ │ │ │ │ └── index.html
│ │ │ │ ├── -p-r-e-p-a-r-e_-u-s-e
│ │ │ │ │ └── index.html
│ │ │ │ ├── -s-t-o-p-e-d
│ │ │ │ │ └── index.html
│ │ │ │ ├── -u-s-e-d
│ │ │ │ │ └── index.html
│ │ │ │ ├── index.html
│ │ │ │ └── value.html
│ │ │ ├── -q-media-model-builder
│ │ │ │ ├── -q-media-model-builder.html
│ │ │ │ ├── add-stream-element.html
│ │ │ │ ├── add-subtitle-element.html
│ │ │ │ ├── build.html
│ │ │ │ └── index.html
│ │ │ ├── -q-media-model
│ │ │ │ ├── index.html
│ │ │ │ ├── is-live.html
│ │ │ │ ├── stream-elements.html
│ │ │ │ └── subtitle-elements.html
│ │ │ ├── -q-play-media-notify-param-keys
│ │ │ │ ├── index.html
│ │ │ │ └── value.html
│ │ │ ├── -q-player-context
│ │ │ │ ├── -q-player-context.html
│ │ │ │ ├── get-player-control-handler.html
│ │ │ │ ├── get-player-render-handler.html
│ │ │ │ └── index.html
│ │ │ ├── -q-player-control-handler
│ │ │ │ ├── -companion
│ │ │ │ │ ├── -i-n-v-a-l-i-d_-q-u-a-l-i-t-y_-i-d.html
│ │ │ │ │ └── index.html
│ │ │ │ ├── add-player-audio-data-listener.html
│ │ │ │ ├── add-player-audio-listener.html
│ │ │ │ ├── add-player-authentication-listener.html
│ │ │ │ ├── add-player-bite-rate-change-listener.html
│ │ │ │ ├── add-player-buffering-change-listener.html
│ │ │ │ ├── add-player-command-not-allow-listener.html
│ │ │ │ ├── add-player-download-change-listener.html
│ │ │ │ ├── add-player-f-p-s-change-listener.html
│ │ │ │ ├── add-player-format-listener.html
│ │ │ │ ├── add-player-media-network-listener.html
│ │ │ │ ├── add-player-progress-change-listener.html
│ │ │ │ ├── add-player-quality-listener.html
│ │ │ │ ├── add-player-s-e-i-data-listener.html
│ │ │ │ ├── add-player-seek-listener.html
│ │ │ │ ├── add-player-shoot-video-listener.html
│ │ │ │ ├── add-player-speed-change-listener.html
│ │ │ │ ├── add-player-subtitle-listener.html
│ │ │ │ ├── add-player-video-data-listener.html
│ │ │ │ ├── add-player-video-decode-type-listener.html
│ │ │ │ ├── add-player-video-frame-size-change-listener.html
│ │ │ │ ├── bite-rate.html
│ │ │ │ ├── buffer-positon.html
│ │ │ │ ├── current-player-state.html
│ │ │ │ ├── current-position.html
│ │ │ │ ├── download-speed.html
│ │ │ │ ├── duration.html
│ │ │ │ ├── fps.html
│ │ │ │ ├── get-current-quality.html
│ │ │ │ ├── get-switching-quality.html
│ │ │ │ ├── index.html
│ │ │ │ ├── is-buffering.html
│ │ │ │ ├── is-mute.html
│ │ │ │ ├── remove-all-player-audio-data-listeners.html
│ │ │ │ ├── remove-all-player-audio-listeners.html
│ │ │ │ ├── remove-all-player-authentications.html
│ │ │ │ ├── remove-all-player-bite-rate-change-listener.html
│ │ │ │ ├── remove-all-player-buffering-change-listener.html
│ │ │ │ ├── remove-all-player-command-not-allow-listener.html
│ │ │ │ ├── remove-all-player-download-change-listener.html
│ │ │ │ ├── remove-all-player-f-p-s-change-listener.html
│ │ │ │ ├── remove-all-player-format-listeners.html
│ │ │ │ ├── remove-all-player-media-network-listener.html
│ │ │ │ ├── remove-all-player-progress-change-listener.html
│ │ │ │ ├── remove-all-player-quality-listener.html
│ │ │ │ ├── remove-all-player-s-e-i-data-listeners.html
│ │ │ │ ├── remove-all-player-seek-listeners.html
│ │ │ │ ├── remove-all-player-shoot-video-listeners.html
│ │ │ │ ├── remove-all-player-speed-change-listener.html
│ │ │ │ ├── remove-all-player-subtitle-listeners.html
│ │ │ │ ├── remove-all-player-video-data-listeners.html
│ │ │ │ ├── remove-all-player-video-decode-type-listener.html
│ │ │ │ ├── remove-all-player-video-frame-size-change-listeners.html
│ │ │ │ ├── remove-player-audio-data-listener.html
│ │ │ │ ├── remove-player-audio-listener.html
│ │ │ │ ├── remove-player-authentication-listener.html
│ │ │ │ ├── remove-player-bite-rate-change-listener.html
│ │ │ │ ├── remove-player-buffering-change-listener.html
│ │ │ │ ├── remove-player-command-not-allow-listener.html
│ │ │ │ ├── remove-player-download-change-listener.html
│ │ │ │ ├── remove-player-f-p-s-change-listener.html
│ │ │ │ ├── remove-player-format-listener.html
│ │ │ │ ├── remove-player-media-network-listener.html
│ │ │ │ ├── remove-player-progress-change-listener.html
│ │ │ │ ├── remove-player-quality-listener.html
│ │ │ │ ├── remove-player-s-e-i-data-listener.html
│ │ │ │ ├── remove-player-seek-listener.html
│ │ │ │ ├── remove-player-shoot-video-listener.html
│ │ │ │ ├── remove-player-speed-change-listener.html
│ │ │ │ ├── remove-player-subtitle-listener.html
│ │ │ │ ├── remove-player-video-data-listener.html
│ │ │ │ ├── remove-player-video-decode-type-listener.html
│ │ │ │ ├── remove-player-video-frame-size-change-listener.html
│ │ │ │ ├── set-speed.html
│ │ │ │ ├── speed.html
│ │ │ │ ├── subtitle-name.html
│ │ │ │ ├── subtitle-text.html
│ │ │ │ ├── switch-quality.html
│ │ │ │ ├── video-height.html
│ │ │ │ └── video-width.html
│ │ │ ├── -q-player-decode-type
│ │ │ │ ├── -companion
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── value-of.html
│ │ │ │ ├── -f-i-r-s-t_-f-r-a-m-e_-a-c-c-e-l
│ │ │ │ │ └── index.html
│ │ │ │ ├── -h-a-r-d-w-a-r-e_-b-u-f-f-e-r
│ │ │ │ │ └── index.html
│ │ │ │ ├── -h-a-r-d-w-a-r-e_-s-u-r-f-a-c-e
│ │ │ │ │ └── index.html
│ │ │ │ ├── -n-o-n-e
│ │ │ │ │ └── index.html
│ │ │ │ ├── -s-o-f-t-w-a-r-e
│ │ │ │ │ └── index.html
│ │ │ │ ├── index.html
│ │ │ │ └── value.html
│ │ │ ├── -q-player-render-handler
│ │ │ │ ├── add-player-render-listener.html
│ │ │ │ ├── index.html
│ │ │ │ ├── remove-all-player-render-listener.html
│ │ │ │ └── remove-player-render-listener.html
│ │ │ ├── -q-player-setting
│ │ │ │ ├── -q-player-blind
│ │ │ │ │ ├── -q-p-l-a-y-e-r_-b-l-i-n-d_-s-e-t-t-i-n-g_-b-l-u-e
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── -q-p-l-a-y-e-r_-b-l-i-n-d_-s-e-t-t-i-n-g_-g-r-e-e-n
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── -q-p-l-a-y-e-r_-b-l-i-n-d_-s-e-t-t-i-n-g_-n-o-n-e
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── -q-p-l-a-y-e-r_-b-l-i-n-d_-s-e-t-t-i-n-g_-r-e-d
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── value.html
│ │ │ │ ├── -q-player-decoder
│ │ │ │ │ ├── -q-p-l-a-y-e-r_-d-e-c-o-d-e-r_-s-e-t-t-i-n-g_-a-u-t-o
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── -q-p-l-a-y-e-r_-d-e-c-o-d-e-r_-s-e-t-t-i-n-g_-f-i-r-s-t_-f-r-a-m-e_-a-c-c-e-l_-p-r-i-o-r-i-t-y
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── -q-p-l-a-y-e-r_-d-e-c-o-d-e-r_-s-e-t-t-i-n-g_-h-a-r-d-w-a-r-e_-p-r-i-o-r-i-t-y
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── -q-p-l-a-y-e-r_-d-e-c-o-d-e-r_-s-e-t-t-i-n-g_-s-o-f-t_-p-r-i-o-r-i-t-y
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── value.html
│ │ │ │ ├── -q-player-mirror
│ │ │ │ │ ├── -q-p-l-a-y-e-r_-m-i-r-r-o-r_-n-o-n-e
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── -q-p-l-a-y-e-r_-m-i-r-r-o-r_-x-y
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── -q-p-l-a-y-e-r_-m-i-r-r-o-r_-x
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── -q-p-l-a-y-e-r_-m-i-r-r-o-r_-y
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── value.html
│ │ │ │ ├── -q-player-render-ratio
│ │ │ │ │ ├── -q-p-l-a-y-e-r_-r-a-t-i-o_-s-e-t-t-i-n-g_-a-u-t-o
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── -q-p-l-a-y-e-r_-r-a-t-i-o_-s-e-t-t-i-n-g_-f-u-l-l_-s-c-r-e-e-n
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── -q-p-l-a-y-e-r_-r-a-t-i-o_-s-e-t-t-i-n-g_-s-t-r-e-t-c-h
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── -q-p-l-a-y-e-r_-r-a-t-i-o_-s-e-t-t-i-n-g_16_9
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── -q-p-l-a-y-e-r_-r-a-t-i-o_-s-e-t-t-i-n-g_4_3
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── value.html
│ │ │ │ ├── -q-player-seek
│ │ │ │ │ ├── -q-p-l-a-y-e-r_-s-e-e-k_-s-e-t-t-i-n-g_-a-c-c-u-r-a-t-e
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── -q-p-l-a-y-e-r_-s-e-e-k_-s-e-t-t-i-n-g_-n-o-r-m-a-l
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── value.html
│ │ │ │ ├── -q-player-setting.html
│ │ │ │ ├── -q-player-start
│ │ │ │ │ ├── -q-p-l-a-y-e-r_-s-t-a-r-t_-s-e-t-t-i-n-g_-p-a-u-s-e
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── -q-p-l-a-y-e-r_-s-t-a-r-t_-s-e-t-t-i-n-g_-p-l-a-y-i-n-g
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── value.html
│ │ │ │ └── index.html
│ │ │ ├── -q-player-state
│ │ │ │ ├── -c-o-m-p-l-e-t-e-d
│ │ │ │ │ └── index.html
│ │ │ │ ├── -companion
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── value-of.html
│ │ │ │ ├── -e-n-d
│ │ │ │ │ └── index.html
│ │ │ │ ├── -e-r-r-o-r
│ │ │ │ │ └── index.html
│ │ │ │ ├── -i-n-i-t
│ │ │ │ │ └── index.html
│ │ │ │ ├── -m-e-d-i-a_-i-t-e-m_-p-r-e-p-a-r-e
│ │ │ │ │ └── index.html
│ │ │ │ ├── -n-o-n-e
│ │ │ │ │ └── index.html
│ │ │ │ ├── -p-a-u-s-e-d_-r-e-n-d-e-r
│ │ │ │ │ └── index.html
│ │ │ │ ├── -p-l-a-y-i-n-g
│ │ │ │ │ └── index.html
│ │ │ │ ├── -p-r-e-p-a-r-e
│ │ │ │ │ └── index.html
│ │ │ │ ├── -r-e-l-e-a-s-e
│ │ │ │ │ └── index.html
│ │ │ │ ├── -s-e-e-k-i-n-g
│ │ │ │ │ └── index.html
│ │ │ │ ├── -s-t-o-p-p-e-d
│ │ │ │ │ └── index.html
│ │ │ │ ├── index.html
│ │ │ │ └── value.html
│ │ │ ├── -q-quality
│ │ │ │ ├── -q-quality.html
│ │ │ │ ├── index.html
│ │ │ │ ├── quality.html
│ │ │ │ ├── url-type.html
│ │ │ │ └── user-type.html
│ │ │ ├── -q-stream-element
│ │ │ │ ├── -q-stream-element.html
│ │ │ │ ├── backup-url.html
│ │ │ │ ├── hls-d-r-m-key.html
│ │ │ │ ├── index.html
│ │ │ │ ├── is-selected.html
│ │ │ │ ├── mp4-drm-key.html
│ │ │ │ ├── mp4-q-n-drm-com-key.html
│ │ │ │ ├── mp4-q-n-drm-file-key.html
│ │ │ │ ├── quality.html
│ │ │ │ ├── referer.html
│ │ │ │ ├── url-type.html
│ │ │ │ ├── url.html
│ │ │ │ ├── user-type.html
│ │ │ │ └── video-render-type.html
│ │ │ ├── -q-subtitle-element
│ │ │ │ ├── -q-subtitle-element.html
│ │ │ │ ├── backup-url.html
│ │ │ │ ├── index.html
│ │ │ │ ├── is-selected.html
│ │ │ │ ├── name.html
│ │ │ │ └── url.html
│ │ │ ├── -q-u-r-l-type
│ │ │ │ ├── -companion
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── value-of.html
│ │ │ │ ├── -n-o-n-e
│ │ │ │ │ └── index.html
│ │ │ │ ├── -q-a-u-d-i-o
│ │ │ │ │ └── index.html
│ │ │ │ ├── -q-a-u-d-i-o_-a-n-d_-v-i-d-e-o
│ │ │ │ │ └── index.html
│ │ │ │ ├── -q-v-i-d-e-o
│ │ │ │ │ └── index.html
│ │ │ │ ├── index.html
│ │ │ │ └── value.html
│ │ │ ├── -q-video-data-callback-type
│ │ │ │ ├── -n-v12
│ │ │ │ │ └── index.html
│ │ │ │ ├── -r-g-b-a
│ │ │ │ │ └── index.html
│ │ │ │ ├── -y-u-v420-p
│ │ │ │ │ └── index.html
│ │ │ │ ├── index.html
│ │ │ │ └── type.html
│ │ │ ├── -q-video-render-type
│ │ │ │ ├── -n-o-n-e
│ │ │ │ │ └── index.html
│ │ │ │ ├── -p-a-n-o-r-a-m-a_-e-q-u-i-r-e-c-t_-a-n-g-u-l-a-r
│ │ │ │ │ └── index.html
│ │ │ │ ├── -p-l-a-n-e
│ │ │ │ │ └── index.html
│ │ │ │ ├── index.html
│ │ │ │ └── value.html
│ │ │ ├── get-audio-quality-list.html
│ │ │ ├── get-subtitle-list.html
│ │ │ ├── get-video-quality-list.html
│ │ │ └── index.html
│ │ ├── com.qiniu.qmedia.render.screen
│ │ │ ├── -q-surface-render-view
│ │ │ │ ├── -q-surface-render-view.html
│ │ │ │ ├── attach-render-handler.html
│ │ │ │ ├── index.html
│ │ │ │ ├── surface-changed.html
│ │ │ │ ├── surface-created.html
│ │ │ │ ├── surface-destroyed.html
│ │ │ │ └── surface-redraw-needed.html
│ │ │ ├── -q-texture-render-view
│ │ │ │ ├── -companion
│ │ │ │ │ ├── -t-a-g.html
│ │ │ │ │ └── index.html
│ │ │ │ ├── -q-texture-render-view.html
│ │ │ │ ├── attach-render-handler.html
│ │ │ │ ├── index.html
│ │ │ │ ├── on-surface-texture-available.html
│ │ │ │ ├── on-surface-texture-destroyed.html
│ │ │ │ ├── on-surface-texture-size-changed.html
│ │ │ │ └── on-surface-texture-updated.html
│ │ │ └── index.html
│ │ ├── com.qiniu.qmedia.ui
│ │ │ ├── -q-surface-player-view
│ │ │ │ ├── -q-surface-player-view.html
│ │ │ │ ├── index.html
│ │ │ │ ├── player-control-handler.html
│ │ │ │ └── player-render-handler.html
│ │ │ ├── -q-texture-player-view
│ │ │ │ ├── -q-texture-player-view.html
│ │ │ │ ├── index.html
│ │ │ │ ├── player-control-handler.html
│ │ │ │ └── player-render-handler.html
│ │ │ └── index.html
│ │ └── package-list
│ │ ├── scripts
│ │ ├── clipboard.js
│ │ ├── main.js
│ │ ├── navigation-loader.js
│ │ ├── pages.json
│ │ ├── platform-content-handler.js
│ │ ├── prism.js
│ │ └── sourceset_dependencies.js
│ │ └── styles
│ │ ├── jetbrains-mono.css
│ │ ├── logo-styles.css
│ │ ├── main.css
│ │ ├── prism.css
│ │ └── style.css
└── qplayer2-ext
│ └── html
│ ├── images
│ ├── anchor-copy-button.svg
│ ├── arrow_down.svg
│ ├── copy-icon.svg
│ ├── copy-successful-icon.svg
│ ├── footer-go-to-link.svg
│ ├── go-to-top-icon.svg
│ ├── logo-icon.svg
│ └── theme-toggle.svg
│ ├── index.html
│ ├── navigation.html
│ ├── qplayer2-ext
│ ├── com.qiniu.qplayer2ext.common.collection
│ │ ├── -collections
│ │ │ ├── -iterator-action-with-index
│ │ │ │ ├── index.html
│ │ │ │ └── run.html
│ │ │ ├── -iterator-action
│ │ │ │ ├── index.html
│ │ │ │ └── run.html
│ │ │ ├── -safe-iterator-collection
│ │ │ │ ├── for-each-with-index.html
│ │ │ │ ├── for-each.html
│ │ │ │ ├── index.html
│ │ │ │ └── is-iterating.html
│ │ │ ├── -safe-iterator-list
│ │ │ │ ├── add-all.html
│ │ │ │ ├── add.html
│ │ │ │ ├── clear.html
│ │ │ │ ├── contains-all.html
│ │ │ │ ├── contains.html
│ │ │ │ ├── for-each-with-index.html
│ │ │ │ ├── for-each.html
│ │ │ │ ├── get.html
│ │ │ │ ├── index-of.html
│ │ │ │ ├── index.html
│ │ │ │ ├── is-empty.html
│ │ │ │ ├── is-iterating.html
│ │ │ │ ├── iterator.html
│ │ │ │ ├── last-index-of.html
│ │ │ │ ├── list-iterator.html
│ │ │ │ ├── remove-all.html
│ │ │ │ ├── remove.html
│ │ │ │ ├── retain-all.html
│ │ │ │ ├── set.html
│ │ │ │ ├── size.html
│ │ │ │ ├── sub-list.html
│ │ │ │ └── to-array.html
│ │ │ ├── -safe-iterator-map
│ │ │ │ ├── clear.html
│ │ │ │ ├── contains-key.html
│ │ │ │ ├── contains-value.html
│ │ │ │ ├── entry-set.html
│ │ │ │ ├── for-each-with-index.html
│ │ │ │ ├── for-each.html
│ │ │ │ ├── get.html
│ │ │ │ ├── index.html
│ │ │ │ ├── is-empty.html
│ │ │ │ ├── is-iterating.html
│ │ │ │ ├── key-set.html
│ │ │ │ ├── put-all.html
│ │ │ │ ├── put.html
│ │ │ │ ├── remove.html
│ │ │ │ ├── size.html
│ │ │ │ └── values.html
│ │ │ ├── index.html
│ │ │ ├── safe-iterator-list.html
│ │ │ └── safe-iterator-map.html
│ │ └── index.html
│ ├── com.qiniu.qplayer2ext.common.measure
│ │ ├── -dp-utils
│ │ │ ├── dp-to-px.html
│ │ │ └── index.html
│ │ └── index.html
│ ├── com.qiniu.qplayer2ext.common.rxjava3
│ │ ├── -completable-subscriber-builder
│ │ │ ├── -completable-subscriber-builder.html
│ │ │ ├── complete-action.html
│ │ │ ├── index.html
│ │ │ └── on-complete.html
│ │ ├── -disposable-helper
│ │ │ ├── -disposable-helper.html
│ │ │ ├── activate.html
│ │ │ ├── add.html
│ │ │ ├── deactivate.html
│ │ │ └── index.html
│ │ ├── -error-subscriber-builder
│ │ │ ├── -error-subscriber-builder.html
│ │ │ ├── error-consumer.html
│ │ │ ├── index.html
│ │ │ └── on-error.html
│ │ ├── -function-action
│ │ │ ├── -function-action.html
│ │ │ ├── function.html
│ │ │ ├── index.html
│ │ │ └── run.html
│ │ ├── -function-consumer
│ │ │ ├── -function-consumer.html
│ │ │ ├── accept.html
│ │ │ ├── function.html
│ │ │ └── index.html
│ │ ├── -maybe-subscriber-builder
│ │ │ ├── -maybe-subscriber-builder.html
│ │ │ ├── complete-action.html
│ │ │ ├── index.html
│ │ │ └── on-complete.html
│ │ ├── -observable-flowable-subscriber-builder
│ │ │ ├── -observable-flowable-subscriber-builder.html
│ │ │ ├── index.html
│ │ │ ├── next-consumer.html
│ │ │ └── on-next.html
│ │ ├── -single-subscriber-builder
│ │ │ ├── -single-subscriber-builder.html
│ │ │ ├── index.html
│ │ │ ├── on-success.html
│ │ │ └── success-consumer.html
│ │ ├── add-to-composite-disposable.html
│ │ ├── add-to-disposable-helper.html
│ │ ├── attach-to-lifecycle.html
│ │ ├── index.html
│ │ ├── into.html
│ │ ├── io-subscribe-ui-observe.html
│ │ ├── never-dispose.html
│ │ ├── run-on-computation-scheduler.html
│ │ ├── run-on-io-scheduler.html
│ │ └── subscribe-by.html
│ ├── com.qiniu.qplayer2ext.common.thread
│ │ ├── -b-thread-pool-executor
│ │ │ ├── -b-thread-pool-executor.html
│ │ │ ├── -companion
│ │ │ │ └── index.html
│ │ │ ├── await-termination.html
│ │ │ ├── execute.html
│ │ │ ├── high-priority.html
│ │ │ ├── index.html
│ │ │ ├── is-shutdown.html
│ │ │ ├── is-terminated.html
│ │ │ ├── shutdown-now.html
│ │ │ └── shutdown.html
│ │ ├── -b-thread-pool
│ │ │ ├── -b-thread-pool.html
│ │ │ ├── -companion
│ │ │ │ ├── index.html
│ │ │ │ ├── init.html
│ │ │ │ └── new-single-thread-executor.html
│ │ │ ├── -pool-reporter
│ │ │ │ ├── index.html
│ │ │ │ ├── report-core-thread-state.html
│ │ │ │ └── report-thread-time-out.html
│ │ │ └── index.html
│ │ ├── -handler-threads
│ │ │ ├── -t-h-r-e-a-d_-b-a-c-k-g-r-o-u-n-d.html
│ │ │ ├── -t-h-r-e-a-d_-b-a-c-k_-i-o.html
│ │ │ ├── -t-h-r-e-a-d_-r-e-p-o-r-t.html
│ │ │ ├── -t-h-r-e-a-d_-s-i-z-e.html
│ │ │ ├── -t-h-r-e-a-d_-u-i.html
│ │ │ ├── -thread-model
│ │ │ │ └── index.html
│ │ │ ├── get-handler.html
│ │ │ ├── get-looper.html
│ │ │ ├── index.html
│ │ │ ├── post-at-front.html
│ │ │ ├── post-delayed.html
│ │ │ ├── post.html
│ │ │ ├── remove.html
│ │ │ ├── run-on-blocking.html
│ │ │ ├── run-on.html
│ │ │ └── running-on.html
│ │ ├── -p-o-o-l_-n-a-m-e_-c-o-r-e.html
│ │ ├── -p-o-o-l_-n-a-m-e_-d-i-s-c-a-r-d.html
│ │ ├── -p-o-o-l_-n-a-m-e_-r-i-s-k.html
│ │ ├── -pool-name
│ │ │ ├── -pool-name.html
│ │ │ └── index.html
│ │ ├── -r-e-p-o-r-t_-w-h-e-n_-d-i-s-c-a-r-d.html
│ │ ├── -r-e-p-o-r-t_-w-h-e-n_-q-u-e-u-e.html
│ │ └── index.html
│ ├── com.qiniu.qplayer2ext.commonplayer.controller
│ │ ├── -common-player-video-switcher
│ │ │ ├── add-video-play-event-listener.html
│ │ │ ├── get-current-playable-params.html
│ │ │ ├── get-current-video-params.html
│ │ │ ├── get-switch-playable-params.html
│ │ │ ├── get-switch-video-params.html
│ │ │ ├── has-next-playable-params.html
│ │ │ ├── has-next-video.html
│ │ │ ├── index.html
│ │ │ ├── on-state-changed.html
│ │ │ ├── on-update.html
│ │ │ ├── remove-video-play-event-listener.html
│ │ │ ├── replay-current-video.html
│ │ │ ├── switch-first-video.html
│ │ │ ├── switch-next-playable-params.html
│ │ │ ├── switch-next-video.html
│ │ │ ├── switch-playable-params-subject.html
│ │ │ ├── switch-video-id-subject.html
│ │ │ ├── switch-video.html
│ │ │ └── update-data-source.html
│ │ ├── -i-common-chain-auto-play-strategy
│ │ │ ├── index.html
│ │ │ ├── on-all-video-completed.html
│ │ │ ├── on-video-completed.html
│ │ │ ├── on-video-item-completed.html
│ │ │ ├── on-video-item-start.html
│ │ │ ├── on-video-item-will-change.html
│ │ │ ├── on-video-will-change.html
│ │ │ ├── start.html
│ │ │ └── stop.html
│ │ ├── -i-common-player-video-switcher
│ │ │ ├── -i-common-video-play-event-listener
│ │ │ │ ├── index.html
│ │ │ │ ├── on-all-video-params-completed.html
│ │ │ │ ├── on-playable-params-completed.html
│ │ │ │ ├── on-playable-params-start.html
│ │ │ │ ├── on-playable-params-will-change.html
│ │ │ │ ├── on-video-params-completed.html
│ │ │ │ ├── on-video-params-set-changed.html
│ │ │ │ ├── on-video-params-start.html
│ │ │ │ └── on-video-params-will-change.html
│ │ │ ├── add-video-play-event-listener.html
│ │ │ ├── index.html
│ │ │ └── remove-video-play-event-listener.html
│ │ └── index.html
│ ├── com.qiniu.qplayer2ext.commonplayer.data
│ │ ├── -common-playable-params
│ │ │ ├── -common-playable-params.html
│ │ │ ├── control-panel-type.html
│ │ │ ├── display-orientation.html
│ │ │ ├── environment-type.html
│ │ │ ├── index.html
│ │ │ ├── media-model.html
│ │ │ └── start-pos.html
│ │ ├── -common-player-data-source
│ │ │ ├── -common-playable-params-updater
│ │ │ │ ├── filter.html
│ │ │ │ ├── index.html
│ │ │ │ └── update.html
│ │ │ ├── -common-player-data-source.html
│ │ │ ├── -data-source-builder
│ │ │ │ ├── -companion
│ │ │ │ │ ├── -t-a-g.html
│ │ │ │ │ └── index.html
│ │ │ │ ├── -data-source-builder.html
│ │ │ │ ├── add-video.html
│ │ │ │ ├── build.html
│ │ │ │ └── index.html
│ │ │ ├── get-first-video-params.html
│ │ │ ├── get-next-video-params-by-id.html
│ │ │ ├── get-playable-params-count.html
│ │ │ ├── get-playable-params.html
│ │ │ ├── get-video-params-list.html
│ │ │ ├── get-video-params.html
│ │ │ ├── index.html
│ │ │ └── update-data-source.html
│ │ ├── -common-video-params
│ │ │ ├── -common-video-params.html
│ │ │ ├── id.html
│ │ │ └── index.html
│ │ ├── -display-orientation
│ │ │ ├── -l-a-n-d-s-c-a-p-e
│ │ │ │ └── index.html
│ │ │ ├── -n-o-n-e
│ │ │ │ └── index.html
│ │ │ ├── -v-e-r-t-i-c-a-l
│ │ │ │ └── index.html
│ │ │ └── index.html
│ │ └── index.html
│ ├── com.qiniu.qplayer2ext.commonplayer.enviroment
│ │ ├── -i-common-player-environment
│ │ │ ├── authentication.html
│ │ │ ├── index.html
│ │ │ ├── name.html
│ │ │ ├── service-types.html
│ │ │ ├── start.html
│ │ │ └── stop.html
│ │ └── index.html
│ ├── com.qiniu.qplayer2ext.commonplayer.external
│ │ ├── -i-common-player-life-cycle-dispatcher
│ │ │ ├── index.html
│ │ │ ├── on-create-view.html
│ │ │ ├── on-create.html
│ │ │ ├── on-destroy-view.html
│ │ │ ├── on-destroy.html
│ │ │ ├── on-pause.html
│ │ │ ├── on-resume.html
│ │ │ ├── on-start.html
│ │ │ ├── on-stop.html
│ │ │ └── on-view-created.html
│ │ ├── -i-common-player-out-video-switcher
│ │ │ ├── get-current-video-id.html
│ │ │ ├── index.html
│ │ │ ├── switch-playable-params-subject.html
│ │ │ ├── switch-video-id-subject.html
│ │ │ └── switch-video.html
│ │ ├── -i-common-player-system-u-i-event-dispatcher
│ │ │ ├── index.html
│ │ │ ├── on-back-pressed.html
│ │ │ ├── on-configuration-changed.html
│ │ │ ├── on-multi-window-mode-changed.html
│ │ │ └── perform-window-focus-changed.html
│ │ └── index.html
│ ├── com.qiniu.qplayer2ext.commonplayer.gravitysensor
│ │ ├── -gravity-sensor-handler
│ │ │ ├── -companion
│ │ │ │ ├── -t-a-g.html
│ │ │ │ └── index.html
│ │ │ ├── index.html
│ │ │ └── set-gravity-sensor-enable.html
│ │ └── index.html
│ ├── com.qiniu.qplayer2ext.commonplayer.layer.control
│ │ ├── -control-panel-config-element
│ │ │ ├── -control-panel-config-element.html
│ │ │ ├── display-orientation.html
│ │ │ ├── index.html
│ │ │ ├── layout-res.html
│ │ │ └── screen-types.html
│ │ ├── -control-panel-config
│ │ │ ├── -control-panel-config.html
│ │ │ ├── elements.html
│ │ │ ├── index.html
│ │ │ └── name.html
│ │ ├── -i-control-widget
│ │ │ ├── index.html
│ │ │ ├── on-widget-active.html
│ │ │ └── on-widget-inactive.html
│ │ ├── -i-player-control-panel-container
│ │ │ ├── hide.html
│ │ │ ├── index.html
│ │ │ ├── is-show.html
│ │ │ └── show.html
│ │ ├── -player-control-panel-container
│ │ │ ├── -companion
│ │ │ │ └── index.html
│ │ │ ├── -control-panel-root
│ │ │ │ ├── -control-panel-root.html
│ │ │ │ ├── display-orientation.html
│ │ │ │ ├── index.html
│ │ │ │ ├── panel-type.html
│ │ │ │ ├── root-view.html
│ │ │ │ ├── screen-type.html
│ │ │ │ └── widgets.html
│ │ │ ├── get-view.html
│ │ │ ├── hide.html
│ │ │ ├── index.html
│ │ │ ├── is-show.html
│ │ │ ├── release.html
│ │ │ ├── show.html
│ │ │ └── switch-screen.html
│ │ └── index.html
│ ├── com.qiniu.qplayer2ext.commonplayer.layer.function
│ │ ├── -base-function-widget
│ │ │ ├── -base-function-widget.html
│ │ │ ├── -configuration
│ │ │ │ ├── different.html
│ │ │ │ └── index.html
│ │ │ ├── function-inset-config.html
│ │ │ ├── function-widget-config.html
│ │ │ ├── get-view.html
│ │ │ ├── index.html
│ │ │ ├── on-configuration-changed.html
│ │ │ ├── on-new-layout-params.html
│ │ │ ├── on-release.html
│ │ │ ├── on-widget-dismiss.html
│ │ │ ├── on-widget-show.html
│ │ │ ├── tag.html
│ │ │ └── token.html
│ │ ├── -function-widget-config
│ │ │ ├── -builder
│ │ │ │ ├── -builder.html
│ │ │ │ ├── build.html
│ │ │ │ ├── change-orientation-disable-when-show.html
│ │ │ │ ├── dismiss-when-activity-stop.html
│ │ │ │ ├── dismiss-when-screen-type-change.html
│ │ │ │ ├── dismiss-when-video-change.html
│ │ │ │ ├── dismiss-when-video-completed.html
│ │ │ │ ├── force-new-instance.html
│ │ │ │ ├── index.html
│ │ │ │ ├── launch-type.html
│ │ │ │ ├── persistent.html
│ │ │ │ └── remove-when-video-change.html
│ │ │ ├── -companion
│ │ │ │ ├── -f-l-a-g_-c-h-a-n-g-e_-o-r-i-e-n-t-a-t-i-o-n_-d-i-s-a-b-l-e_-w-h-e-n_-s-h-o-w.html
│ │ │ │ ├── -f-l-a-g_-d-i-s-m-i-s-s_-a-c-t-i-v-i-t-y_-s-t-o-p.html
│ │ │ │ ├── -f-l-a-g_-d-i-s-m-i-s-s_-c-h-a-n-g-e_-v-i-d-e-o.html
│ │ │ │ ├── -f-l-a-g_-d-i-s-m-i-s-s_-s-c-r-e-e-n_-m-o-d-e_-c-h-a-n-g-e.html
│ │ │ │ ├── -f-l-a-g_-d-i-s-m-i-s-s_-v-i-d-e-o_-c-o-m-p-l-e-t-e-d.html
│ │ │ │ ├── -f-l-a-g_-p-e-r-s-i-s-t-e-n-t_-w-i-d-g-e-t.html
│ │ │ │ ├── -f-l-a-g_-r-e-m-o-v-e_-c-h-a-n-g-e_-v-i-d-e-o.html
│ │ │ │ └── index.html
│ │ │ ├── -launch-type
│ │ │ │ ├── -normal
│ │ │ │ │ └── index.html
│ │ │ │ ├── -singleton
│ │ │ │ │ └── index.html
│ │ │ │ ├── index.html
│ │ │ │ └── type.html
│ │ │ ├── flag.html
│ │ │ ├── force-new-instance.html
│ │ │ ├── index.html
│ │ │ ├── launch-type.html
│ │ │ └── to-string.html
│ │ ├── -function-widget-inset-config
│ │ │ ├── -function-widget-inset-config.html
│ │ │ ├── content-bottom-padding.html
│ │ │ ├── content-left-padding.html
│ │ │ ├── content-right-padding.html
│ │ │ ├── content-top-padding.html
│ │ │ ├── index.html
│ │ │ └── support.html
│ │ ├── -function-widget-layout-params
│ │ │ ├── -companion
│ │ │ │ ├── -f-l-a-g_-t-o-u-c-h_-e-n-a-b-l-e.html
│ │ │ │ ├── -f-l-a-g_-t-o-u-c-h_-o-u-t-s-i-d-e_-d-i-s-m-i-s-s.html
│ │ │ │ ├── -n-o_-a-n-i-m-a-t-i-o-n.html
│ │ │ │ ├── index.html
│ │ │ │ └── layout-type-alias.html
│ │ │ ├── -function-type
│ │ │ │ ├── -d-i-a-l-o-g
│ │ │ │ │ └── index.html
│ │ │ │ ├── -e-m-b-e-d-d-e-d_-v-i-e-w
│ │ │ │ │ └── index.html
│ │ │ │ ├── -n-o-r-m-a-l
│ │ │ │ │ └── index.html
│ │ │ │ ├── -p-o-p-u-p_-w-i-n-d-o-w
│ │ │ │ │ └── index.html
│ │ │ │ ├── index.html
│ │ │ │ └── type.html
│ │ │ ├── -function-widget-layout-params.html
│ │ │ ├── -layout-align-type
│ │ │ │ ├── -b-o-t-t-o-m
│ │ │ │ │ └── index.html
│ │ │ │ ├── -c-e-n-t-e-r
│ │ │ │ │ └── index.html
│ │ │ │ ├── -l-e-f-t
│ │ │ │ │ └── index.html
│ │ │ │ ├── -r-i-g-h-t
│ │ │ │ │ └── index.html
│ │ │ │ ├── -t-o-p
│ │ │ │ │ └── index.html
│ │ │ │ ├── -u-n-d-e-f-i-n-e-d
│ │ │ │ │ └── index.html
│ │ │ │ ├── align.html
│ │ │ │ └── index.html
│ │ │ ├── background-drawable.html
│ │ │ ├── bottom-margin.html
│ │ │ ├── different.html
│ │ │ ├── enter-anim.html
│ │ │ ├── exit-anim.html
│ │ │ ├── flag.html
│ │ │ ├── function-type.html
│ │ │ ├── height.html
│ │ │ ├── index.html
│ │ │ ├── layout-type.html
│ │ │ ├── left-margin.html
│ │ │ ├── right-margin.html
│ │ │ ├── top-margin.html
│ │ │ ├── touch-enable.html
│ │ │ ├── touch-outside-dismiss.html
│ │ │ └── width.html
│ │ ├── -i-on-function-widget-visibility-change-listener
│ │ │ ├── index.html
│ │ │ ├── on-widget-dismiss.html
│ │ │ └── on-widget-show.html
│ │ ├── -player-function-container
│ │ │ ├── -companion
│ │ │ │ ├── -empty-layout-params.html
│ │ │ │ ├── -t-a-g.html
│ │ │ │ └── index.html
│ │ │ ├── -function-widget-token
│ │ │ │ ├── -function-widget-inset-config
│ │ │ │ │ ├── -function-widget-inset-config.html
│ │ │ │ │ ├── content-bottom-padding.html
│ │ │ │ │ ├── content-left-padding.html
│ │ │ │ │ ├── content-right-padding.html
│ │ │ │ │ ├── content-top-padding.html
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── support.html
│ │ │ │ ├── -function-widget-token.html
│ │ │ │ ├── -widget-changed-listener
│ │ │ │ │ ├── index.html
│ │ │ │ │ ├── on-dismiss.html
│ │ │ │ │ ├── on-removed.html
│ │ │ │ │ └── on-show.html
│ │ │ │ ├── clazz.html
│ │ │ │ ├── id.html
│ │ │ │ ├── index.html
│ │ │ │ ├── is-removed.html
│ │ │ │ ├── is-showing.html
│ │ │ │ ├── to-string.html
│ │ │ │ └── widget-changed-listener.html
│ │ │ ├── add-on-function-widget-visibility-change-listener.html
│ │ │ ├── get-view.html
│ │ │ ├── hide-all-widget.html
│ │ │ ├── hide-widget.html
│ │ │ ├── index.html
│ │ │ ├── on-back-pressed.html
│ │ │ ├── release.html
│ │ │ ├── remove-on-function-widget-visibility-change-listener.html
│ │ │ ├── remove-widget.html
│ │ │ ├── show-widget.html
│ │ │ └── update-widget.html
│ │ └── index.html
│ ├── com.qiniu.qplayer2ext.commonplayer.layer.gesture.detector
│ │ ├── -rotate-gesture-detector
│ │ │ ├── -on-rotate-gesture-listener
│ │ │ │ ├── index.html
│ │ │ │ ├── on-rotate-begin.html
│ │ │ │ ├── on-rotate-end.html
│ │ │ │ └── on-rotate.html
│ │ │ ├── -rotate-gesture-detector.html
│ │ │ ├── -simple-rotate-gesture-listener
│ │ │ │ ├── index.html
│ │ │ │ ├── on-rotate-begin.html
│ │ │ │ ├── on-rotate-end.html
│ │ │ │ └── on-rotate.html
│ │ │ ├── get-degree.html
│ │ │ ├── index.html
│ │ │ ├── is-in-progress.html
│ │ │ └── on-touch-event.html
│ │ └── index.html
│ ├── com.qiniu.qplayer2ext.commonplayer.layer.gesture
│ │ ├── -horizontal-scroll-listener
│ │ │ ├── index.html
│ │ │ ├── on-cancel.html
│ │ │ ├── on-scroll-start.html
│ │ │ ├── on-scroll-stop.html
│ │ │ └── on-scroll.html
│ │ ├── -i-on-resizable-gesture-listener
│ │ │ ├── index.html
│ │ │ ├── on-resizable-gesture-end.html
│ │ │ └── on-resizable-gesture-start.html
│ │ ├── -layer-inner-resizable-gesture-listener
│ │ │ ├── index.html
│ │ │ ├── on-down.html
│ │ │ ├── on-fling.html
│ │ │ ├── on-long-press.html
│ │ │ ├── on-resizable-gesture-end.html
│ │ │ ├── on-resizable-gesture-start.html
│ │ │ ├── on-rotate-begin.html
│ │ │ ├── on-rotate-end.html
│ │ │ ├── on-rotate.html
│ │ │ ├── on-scale-begin.html
│ │ │ ├── on-scale-end.html
│ │ │ ├── on-scale.html
│ │ │ ├── on-scroll.html
│ │ │ ├── on-show-press.html
│ │ │ └── on-single-tap-up.html
│ │ ├── -on-double-tap-listener
│ │ │ ├── index.html
│ │ │ └── on-double-tap.html
│ │ ├── -on-down-listener
│ │ │ ├── index.html
│ │ │ └── on-down.html
│ │ ├── -on-long-press-listener
│ │ │ ├── index.html
│ │ │ ├── on-long-press-end.html
│ │ │ └── on-long-press.html
│ │ ├── -on-single-tap-listener
│ │ │ ├── index.html
│ │ │ └── on-single-tap.html
│ │ ├── -on-touch-listener
│ │ │ ├── index.html
│ │ │ └── on-touch.html
│ │ ├── -on-two-finger-double-tap-listener
│ │ │ ├── index.html
│ │ │ └── on-two-finger-double-tap.html
│ │ ├── -player-gesture-layer
│ │ │ ├── add-on-double-tap-listener.html
│ │ │ ├── add-on-down-listener.html
│ │ │ ├── add-on-long-press-listener.html
│ │ │ ├── add-on-single-tap-listener.html
│ │ │ ├── add-on-two-finger-double-tap-listener.html
│ │ │ ├── forbidden-inner-touch-event.html
│ │ │ ├── forbidden-resize-gesture.html
│ │ │ ├── get-gesture-height.html
│ │ │ ├── get-gesture-width.html
│ │ │ ├── get-view.html
│ │ │ ├── index.html
│ │ │ ├── is-resize-gesture-forbidden.html
│ │ │ ├── remove-on-double-tap-listener.html
│ │ │ ├── remove-on-down-listener.html
│ │ │ ├── remove-on-long-press-listener.html
│ │ │ ├── remove-on-single-tap-listener.html
│ │ │ ├── remove-on-two-finger-double-tap-listener.html
│ │ │ ├── set-horizontal-scroll-listener.html
│ │ │ ├── set-on-touch-listener.html
│ │ │ ├── set-resizable-gesture-listener.html
│ │ │ ├── set-vertical-scroll-left-listener.html
│ │ │ └── set-vertical-scroll-right-listener.html
│ │ ├── -player-gesture-listener
│ │ │ ├── -player-gesture-listener.html
│ │ │ ├── cancel.html
│ │ │ ├── index.html
│ │ │ ├── on-double-tap.html
│ │ │ ├── on-down.html
│ │ │ ├── on-long-press.html
│ │ │ ├── on-scroll.html
│ │ │ ├── on-single-tap-confirmed.html
│ │ │ ├── on-up.html
│ │ │ ├── set-gesture-size.html
│ │ │ └── set-touch-gesture-listener.html
│ │ ├── -vertical-scroll-left-listener
│ │ │ ├── index.html
│ │ │ ├── on-cancel.html
│ │ │ ├── on-scroll-start.html
│ │ │ ├── on-scroll-stop.html
│ │ │ └── on-scroll.html
│ │ ├── -vertical-scroll-right-listener
│ │ │ ├── index.html
│ │ │ ├── on-cancel.html
│ │ │ ├── on-scroll-start.html
│ │ │ ├── on-scroll-stop.html
│ │ │ └── on-scroll.html
│ │ └── index.html
│ ├── com.qiniu.qplayer2ext.commonplayer.layer.toast
│ │ ├── -i-player-toast-container
│ │ │ ├── dismiss-toast.html
│ │ │ ├── index.html
│ │ │ ├── refresh-toast.html
│ │ │ ├── set-padding.html
│ │ │ └── show-toast.html
│ │ ├── -player-toast-config
│ │ │ ├── -d-u-r-a-t-i-o-n_-f-o-r-e-v-e-r.html
│ │ │ ├── -d-u-r-a-t-i-o-n_-n-o-n-e.html
│ │ │ ├── -d-u-r-a-t-i-o-n_1.html
│ │ │ ├── -d-u-r-a-t-i-o-n_10.html
│ │ │ ├── -d-u-r-a-t-i-o-n_2.html
│ │ │ ├── -d-u-r-a-t-i-o-n_3.html
│ │ │ ├── -d-u-r-a-t-i-o-n_4.html
│ │ │ ├── -d-u-r-a-t-i-o-n_5.html
│ │ │ ├── -d-u-r-a-t-i-o-n_6.html
│ │ │ ├── -d-u-r-a-t-i-o-n_7.html
│ │ │ ├── -d-u-r-a-t-i-o-n_8.html
│ │ │ ├── -d-u-r-a-t-i-o-n_9.html
│ │ │ ├── -e-x-t-r-a_-a-c-t-i-o-n_-n-e-e-d_-c-l-o-s-e.html
│ │ │ ├── -e-x-t-r-a_-a-c-t-i-o-n_-t-e-x-t.html
│ │ │ ├── -e-x-t-r-a_-a-c-t-i-o-n_-t-e-x-t_-c-o-l-o-r_-r-e-s_-i-d.html
│ │ │ ├── -e-x-t-r-a_-b-g_-d-r-a-w-a-b-l-e_-r-e-s_-i-d.html
│ │ │ ├── -e-x-t-r-a_-b-g_-f-i-n-a-l_-d-r-a-w-a-b-l-e_-r-e-s_-i-d.html
│ │ │ ├── -e-x-t-r-a_-d-a-n-m-a-k-u_-r-e-c-o-m-m-e-n-d-e-d.html
│ │ │ ├── -e-x-t-r-a_-d-a-n-m-a-k-u_-r-e-m-o-t-e_-i-d.html
│ │ │ ├── -e-x-t-r-a_-f-i-n-a-l_-a-c-t-i-o-n_-t-e-x-t_-c-o-l-o-r_-r-e-s_-i-d.html
│ │ │ ├── -e-x-t-r-a_-f-r-o-n-t_-d-r-a-w-a-b-l-e_-r-e-s_-i-d.html
│ │ │ ├── -e-x-t-r-a_-t-i-t-l-e.html
│ │ │ ├── -e-x-t-r-a_-t-i-t-l-e_-b-o-l-d.html
│ │ │ ├── -e-x-t-r-a_-t-i-t-l-e_-c-o-l-o-r.html
│ │ │ ├── -e-x-t-r-a_-t-i-t-l-e_-s-i-z-e.html
│ │ │ ├── -e-x-t-r-a_-t-o-a-s-t_-l-e-n-g-t-h.html
│ │ │ ├── -l-e-v-e-l_-f-o-u-r-t-h.html
│ │ │ ├── -l-e-v-e-l_-h-i-g-h-e-s-t.html
│ │ │ ├── -l-e-v-e-l_-l-o-w-e-s-t.html
│ │ │ ├── -l-e-v-e-l_-s-e-c-o-n-d.html
│ │ │ ├── -l-e-v-e-l_-t-h-i-r-d.html
│ │ │ ├── -l-o-c-a-t_-c-e-n-t-e-r.html
│ │ │ ├── -l-o-c-a-t_-l-e-f-t_-s-i-d-e.html
│ │ │ ├── -level
│ │ │ │ └── index.html
│ │ │ ├── -location
│ │ │ │ └── index.html
│ │ │ ├── -q-u-e-u-e_-i-n-s-e-r-t.html
│ │ │ ├── -q-u-e-u-e_-r-e-f-r-e-s-h.html
│ │ │ ├── -queue-type
│ │ │ │ └── index.html
│ │ │ ├── -t-y-p-e_-a-c-t-i-o-n.html
│ │ │ ├── -t-y-p-e_-a-c-t-i-o-n_-a-n-i-m-a-t-i-o-n.html
│ │ │ ├── -t-y-p-e_-c-u-s-t-o-m.html
│ │ │ ├── -t-y-p-e_-e-n-d.html
│ │ │ ├── -t-y-p-e_-n-o-r-m-a-l.html
│ │ │ ├── -t-y-p-e_-s-t-a-r-t.html
│ │ │ ├── -t-y-p-e_-s-y-s-t-e-m.html
│ │ │ ├── -toast-duration
│ │ │ │ └── index.html
│ │ │ ├── -toast-item-type
│ │ │ │ └── index.html
│ │ │ ├── get-action-text.html
│ │ │ ├── get-title-bold.html
│ │ │ ├── get-title.html
│ │ │ └── index.html
│ │ ├── -player-toast-container
│ │ │ ├── -companion
│ │ │ │ └── index.html
│ │ │ ├── dismiss-toast.html
│ │ │ ├── get-view.html
│ │ │ ├── index.html
│ │ │ ├── refresh-toast.html
│ │ │ ├── set-padding.html
│ │ │ └── show-toast.html
│ │ ├── -player-toast
│ │ │ ├── -builder
│ │ │ │ ├── -builder.html
│ │ │ │ ├── build.html
│ │ │ │ ├── duration.html
│ │ │ │ ├── index.html
│ │ │ │ ├── level.html
│ │ │ │ ├── location.html
│ │ │ │ ├── message-click-listener.html
│ │ │ │ ├── queue-type.html
│ │ │ │ ├── refresh-duration.html
│ │ │ │ ├── set-custom-view.html
│ │ │ │ ├── set-extra-boolean.html
│ │ │ │ ├── set-extra-color-resource.html
│ │ │ │ ├── set-extra-drawable-resource.html
│ │ │ │ ├── set-extra-float.html
│ │ │ │ ├── set-extra-int.html
│ │ │ │ ├── set-extra-layout-id.html
│ │ │ │ ├── set-extra-parcelable.html
│ │ │ │ ├── set-extra-string.html
│ │ │ │ └── toast-item-type.html
│ │ │ ├── -companion
│ │ │ │ ├── -t-a-g.html
│ │ │ │ ├── generate-create-time-millis.html
│ │ │ │ └── index.html
│ │ │ ├── -message-click-listener
│ │ │ │ ├── -companion
│ │ │ │ │ ├── -c-l-i-c-k_-i-d1.html
│ │ │ │ │ └── index.html
│ │ │ │ ├── index.html
│ │ │ │ ├── on-action.html
│ │ │ │ └── on-dismiss.html
│ │ │ ├── click-listener.html
│ │ │ ├── clone.html
│ │ │ ├── create-time.html
│ │ │ ├── custom-view.html
│ │ │ ├── duration.html
│ │ │ ├── get-extra-boolean-value.html
│ │ │ ├── get-extra-float-value.html
│ │ │ ├── get-extra-int-value.html
│ │ │ ├── get-extra-parcelable.html
│ │ │ ├── get-extra-string.html
│ │ │ ├── index.html
│ │ │ ├── level.html
│ │ │ ├── location.html
│ │ │ ├── queue-type.html
│ │ │ ├── refresh-duration.html
│ │ │ ├── set-extra-boolean.html
│ │ │ ├── set-extra-color-resource.html
│ │ │ ├── set-extra-drawable-resource.html
│ │ │ ├── set-extra-float.html
│ │ │ ├── set-extra-int.html
│ │ │ ├── set-extra-layout-id.html
│ │ │ ├── set-extra-parcelable.html
│ │ │ ├── set-extra-string.html
│ │ │ └── toast-type.html
│ │ └── index.html
│ ├── com.qiniu.qplayer2ext.commonplayer.screen
│ │ ├── -common-player-screen-handler
│ │ │ ├── add-screen-changed-listener.html
│ │ │ ├── get-current-screen-type.html
│ │ │ ├── index.html
│ │ │ ├── is-gravity-orientation-enable.html
│ │ │ ├── remove-all-screen-changed-listeners.html
│ │ │ ├── remove-screen-changed-listener.html
│ │ │ └── switch-screen-type.html
│ │ ├── -i-common-player-screen-changed-listener
│ │ │ ├── index.html
│ │ │ └── on-screen-type-changed.html
│ │ ├── -i-common-player-screen-handler
│ │ │ ├── add-screen-changed-listener.html
│ │ │ ├── get-current-screen-type.html
│ │ │ ├── index.html
│ │ │ ├── remove-screen-changed-listener.html
│ │ │ └── switch-screen-type.html
│ │ ├── -i-window-inset-observer
│ │ │ ├── index.html
│ │ │ └── on-window-inset-changed.html
│ │ ├── -screen-type
│ │ │ ├── -f-u-l-l_-s-c-r-e-e-n
│ │ │ │ └── index.html
│ │ │ ├── -h-a-l-f_-s-c-r-e-e-n
│ │ │ │ └── index.html
│ │ │ ├── -n-o-n-e
│ │ │ │ └── index.html
│ │ │ ├── -r-e-v-e-r-s-e_-f-u-l-l_-s-c-r-e-e-n
│ │ │ │ └── index.html
│ │ │ └── index.html
│ │ ├── -window-inset
│ │ │ ├── -window-inset.html
│ │ │ ├── bottom-padding.html
│ │ │ ├── index.html
│ │ │ ├── left-padding.html
│ │ │ ├── right-padding.html
│ │ │ └── top-padding.html
│ │ └── index.html
│ ├── com.qiniu.qplayer2ext.commonplayer.service
│ │ ├── -i-common-player-environment-service-manager
│ │ │ ├── get-player-service.html
│ │ │ └── index.html
│ │ ├── -i-player-service-manager
│ │ │ ├── bind-service.html
│ │ │ ├── index.html
│ │ │ ├── release.html
│ │ │ ├── start-service.html
│ │ │ ├── stop-service.html
│ │ │ └── unbind-service.html
│ │ ├── -i-player-service-owner
│ │ │ ├── index.html
│ │ │ ├── name.html
│ │ │ ├── service.html
│ │ │ ├── start.html
│ │ │ └── stop.html
│ │ ├── -i-player-service
│ │ │ ├── index.html
│ │ │ ├── on-player-reset.html
│ │ │ ├── on-start.html
│ │ │ ├── on-stop.html
│ │ │ └── service-config.html
│ │ ├── -player-service-manager
│ │ │ ├── -client
│ │ │ │ ├── -client.html
│ │ │ │ ├── index.html
│ │ │ │ ├── on-player-service-stop.html
│ │ │ │ └── service.html
│ │ │ ├── -companion
│ │ │ │ └── index.html
│ │ │ ├── -player-service-manager.html
│ │ │ ├── -service-config
│ │ │ │ ├── -companion
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── obtain.html
│ │ │ │ ├── index.html
│ │ │ │ └── is-persistent.html
│ │ │ ├── -service-descriptor
│ │ │ │ ├── -companion
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── obtain.html
│ │ │ │ ├── clazz.html
│ │ │ │ ├── id.html
│ │ │ │ ├── index.html
│ │ │ │ └── to-string.html
│ │ │ ├── bind-service.html
│ │ │ ├── index.html
│ │ │ ├── release.html
│ │ │ ├── start-service.html
│ │ │ ├── stop-service.html
│ │ │ └── unbind-service.html
│ │ └── index.html
│ ├── com.qiniu.qplayer2ext.commonplayer.view
│ │ ├── -fixed-width-text-view
│ │ │ ├── -fixed-width-text-view.html
│ │ │ ├── index.html
│ │ │ ├── request-layout.html
│ │ │ └── set-text.html
│ │ └── index.html
│ ├── com.qiniu.qplayer2ext.commonplayer
│ │ ├── -common-player-config
│ │ │ ├── -builder
│ │ │ │ ├── -builder.html
│ │ │ │ ├── add-control-panel.html
│ │ │ │ ├── add-enviroment.html
│ │ │ │ ├── add-service-owner.html
│ │ │ │ ├── build.html
│ │ │ │ ├── enable-control-panel.html
│ │ │ │ ├── enable-function-widget.html
│ │ │ │ ├── enable-gesture.html
│ │ │ │ ├── enable-screen-render.html
│ │ │ │ ├── enable-toast.html
│ │ │ │ ├── index.html
│ │ │ │ ├── set-author-id.html
│ │ │ │ ├── set-blind-type.html
│ │ │ │ ├── set-common-player-screen-changed-listener.html
│ │ │ │ ├── set-context.html
│ │ │ │ ├── set-decode-type.html
│ │ │ │ ├── set-log-level.html
│ │ │ │ ├── set-logic-provider.html
│ │ │ │ ├── set-mirror-type.html
│ │ │ │ ├── set-mute.html
│ │ │ │ ├── set-player-data-source.html
│ │ │ │ ├── set-render-ratio.html
│ │ │ │ ├── set-root-u-i-contanier.html
│ │ │ │ ├── set-rotation.html
│ │ │ │ ├── set-s-e-i-enable.html
│ │ │ │ ├── set-scale.html
│ │ │ │ ├── set-seek-mode.html
│ │ │ │ ├── set-so-path.html
│ │ │ │ ├── set-speed.html
│ │ │ │ ├── set-start-action.html
│ │ │ │ └── set-subtitle-enable.html
│ │ │ ├── -common-player-config.html
│ │ │ ├── -common-player-core-config
│ │ │ │ ├── -common-player-core-config.html
│ │ │ │ ├── activity.html
│ │ │ │ ├── angle.html
│ │ │ │ ├── author-id.html
│ │ │ │ ├── blind-type.html
│ │ │ │ ├── common-player-screen-changed-listener.html
│ │ │ │ ├── context.html
│ │ │ │ ├── control-container-config.html
│ │ │ │ ├── control-panel-enable.html
│ │ │ │ ├── decode-type.html
│ │ │ │ ├── enviroments.html
│ │ │ │ ├── function-widget-enable.html
│ │ │ │ ├── gesture-enable.html
│ │ │ │ ├── index.html
│ │ │ │ ├── log-level.html
│ │ │ │ ├── logic-provider.html
│ │ │ │ ├── mirror-type.html
│ │ │ │ ├── mute.html
│ │ │ │ ├── player-data-source.html
│ │ │ │ ├── render-ratio.html
│ │ │ │ ├── root-container.html
│ │ │ │ ├── scale.html
│ │ │ │ ├── screen-render-enable.html
│ │ │ │ ├── screen-render-type.html
│ │ │ │ ├── seek-mode.html
│ │ │ │ ├── sei-enable.html
│ │ │ │ ├── service-owners.html
│ │ │ │ ├── so-path.html
│ │ │ │ ├── speed.html
│ │ │ │ ├── start-action.html
│ │ │ │ ├── subtitle-enable.html
│ │ │ │ └── toast-enable.html
│ │ │ ├── -screen-render-type
│ │ │ │ ├── -s-u-r-f-a-c-e_-v-i-e-w
│ │ │ │ │ └── index.html
│ │ │ │ ├── -t-e-x-t-u-r-e_-v-i-e-w
│ │ │ │ │ └── index.html
│ │ │ │ └── index.html
│ │ │ ├── index.html
│ │ │ └── player-core-config.html
│ │ ├── -common-player-core
│ │ │ ├── -common-player-core.html
│ │ │ ├── bind-common-player-core.html
│ │ │ ├── get-common-player-screen-handler.html
│ │ │ ├── get-player-enviroment-service-manager.html
│ │ │ ├── index.html
│ │ │ ├── logic-provider.html
│ │ │ ├── m-android-context.html
│ │ │ ├── m-common-player-video-switcher.html
│ │ │ ├── m-player-context.html
│ │ │ ├── player-control-panel-container.html
│ │ │ ├── player-data-source.html
│ │ │ ├── player-function-widget-container.html
│ │ │ ├── player-gesture-layer.html
│ │ │ ├── player-toast-container.html
│ │ │ └── release.html
│ │ ├── -common-player
│ │ │ ├── -common-player.html
│ │ │ ├── -companion
│ │ │ │ └── index.html
│ │ │ ├── index.html
│ │ │ ├── player-video-switcher.html
│ │ │ └── release.html
│ │ ├── -i-common-player-core-binder-proxy
│ │ │ ├── bind-common-player-core.html
│ │ │ └── index.html
│ │ ├── -i-common-player-core-binder
│ │ │ ├── bind-player-core.html
│ │ │ └── index.html
│ │ ├── -i-logic-provider
│ │ │ └── index.html
│ │ └── index.html
│ └── package-list
│ ├── scripts
│ ├── clipboard.js
│ ├── main.js
│ ├── navigation-loader.js
│ ├── pages.json
│ ├── platform-content-handler.js
│ ├── prism.js
│ └── sourceset_dependencies.js
│ └── styles
│ ├── jetbrains-mono.css
│ ├── logo-styles.css
│ ├── main.css
│ ├── prism.css
│ └── style.css
├── Qplayer2Demo
├── .gitignore
├── .idea
│ ├── .name
│ ├── compiler.xml
│ ├── jarRepositories.xml
│ ├── kotlinc.xml
│ └── vcs.xml
├── app
│ ├── .gitignore
│ ├── build.gradle
│ ├── libs
│ │ └── qndroid-miku-delivery-v1.1.2.jar
│ ├── proguard-rules.pro
│ └── src
│ │ └── main
│ │ ├── AndroidManifest.xml
│ │ ├── TODO.md
│ │ ├── ic_qplayer2_launcher2-playstore.png
│ │ ├── java
│ │ └── com
│ │ │ └── qiniu
│ │ │ └── qplayer2
│ │ │ ├── application
│ │ │ ├── QPlayerApplication.kt
│ │ │ └── QPlayerApplicationContext.kt
│ │ │ ├── common
│ │ │ ├── system
│ │ │ │ ├── FileUtils.kt
│ │ │ │ ├── PermissionHelper.kt
│ │ │ │ ├── RomUtils.java
│ │ │ │ ├── SaveUtils.kt
│ │ │ │ └── SystemProperties.java
│ │ │ └── type
│ │ │ │ ├── CharSequenceUtils.java
│ │ │ │ ├── ObjectUtils.java
│ │ │ │ └── StringUtils.java
│ │ │ ├── logic
│ │ │ ├── BasePlayerControlVM.kt
│ │ │ ├── BasePlayerRenderVM.kt
│ │ │ ├── PlayerBiteRateVM.kt
│ │ │ ├── PlayerBufferingVM.kt
│ │ │ ├── PlayerDownloadVM.kt
│ │ │ ├── PlayerFPSVM.kt
│ │ │ ├── PlayerFirstFrameVM.kt
│ │ │ ├── PlayerPausePlayVM.kt
│ │ │ ├── PlayerProgressVM.kt
│ │ │ └── PlayerSettingVM.kt
│ │ │ ├── repository
│ │ │ ├── common
│ │ │ │ └── SharedPerencesHelper.kt
│ │ │ ├── setting
│ │ │ │ └── PlayerSettingRespostory.kt
│ │ │ └── shortvideo
│ │ │ │ ├── ModelFactory.java
│ │ │ │ ├── ShortVideoApiService.kt
│ │ │ │ ├── UpgradeInfo.java
│ │ │ │ └── VideoItem.java
│ │ │ ├── tools
│ │ │ ├── AudioFrame.kt
│ │ │ ├── BaseFrame.kt
│ │ │ ├── MediaEncoder.kt
│ │ │ ├── MediaMuxerWrapper.kt
│ │ │ ├── MediaRecord.kt
│ │ │ ├── MediaType.kt
│ │ │ └── VideoFrame.kt
│ │ │ └── ui
│ │ │ ├── common
│ │ │ ├── notch
│ │ │ │ ├── DefaultNotchScreenSupport.java
│ │ │ │ ├── HwNotchScreenSupport.java
│ │ │ │ ├── INotchScreenSupport.java
│ │ │ │ ├── MeiZuNotchScreenSupport.java
│ │ │ │ ├── MiNotchScreenSupport.java
│ │ │ │ ├── NotchCompat.java
│ │ │ │ ├── OnePLusNotchScreenSupport.java
│ │ │ │ ├── OppoNotchScreenSupport.java
│ │ │ │ ├── PNotchScreenSupport.java
│ │ │ │ ├── SamsungNotchScreenSupport.java
│ │ │ │ └── VivoNotchScreenSupport.java
│ │ │ └── statusbar
│ │ │ │ └── StatusBarCompat.java
│ │ │ ├── page
│ │ │ ├── doubleplayer
│ │ │ │ └── DoublePlayerActivity.kt
│ │ │ ├── longvideo
│ │ │ │ ├── LongCommonPlayerScreenChangedListener.kt
│ │ │ │ ├── LongControlPanelType.kt
│ │ │ │ ├── LongEnviromentType.kt
│ │ │ │ ├── LongLogicProvider.kt
│ │ │ │ ├── LongPlayableParams.kt
│ │ │ │ ├── LongPlayerDataSourceFactory.kt
│ │ │ │ ├── LongPlayerEnviroment.kt
│ │ │ │ ├── LongVideoActivity.kt
│ │ │ │ ├── LongVideoParams.kt
│ │ │ │ └── service
│ │ │ │ │ ├── ServiceOwnerType.kt
│ │ │ │ │ ├── buffering
│ │ │ │ │ ├── IPlayerBufferingService.kt
│ │ │ │ │ ├── PlayerBufferingService.kt
│ │ │ │ │ └── PlayerBufferingServiceOwner.kt
│ │ │ │ │ ├── controlpanelcontainervisible
│ │ │ │ │ ├── IPlayerControlPanelContainerVisibleService.kt
│ │ │ │ │ ├── PlayerControlPanelContainerVisibleService.kt
│ │ │ │ │ └── PlayerControlPanelContainerVisibleServiceOwner.kt
│ │ │ │ │ ├── network
│ │ │ │ │ ├── IPlayerNetworkService.kt
│ │ │ │ │ ├── PlayerNetworkService.kt
│ │ │ │ │ └── PlayerNetworkServiceOwner.kt
│ │ │ │ │ ├── panorama
│ │ │ │ │ ├── IPlayerPanoramaTouchSerivice.kt
│ │ │ │ │ ├── PanoramaOnResizableGestureListener.java
│ │ │ │ │ ├── PlayerPanoramaTouchSerivice.kt
│ │ │ │ │ └── PlayerPanoramaTouchSeriviceOwner.kt
│ │ │ │ │ ├── shoot
│ │ │ │ │ ├── IPlayerCaptureService.kt
│ │ │ │ │ ├── PlayerCaptureService.kt
│ │ │ │ │ └── PlayerShootVideoServiceOwner.kt
│ │ │ │ │ ├── subtitle
│ │ │ │ │ ├── IPlayerSubtitleService.kt
│ │ │ │ │ ├── PlayerSubtitleService.kt
│ │ │ │ │ └── PlayerSubtitleServiceOwner.kt
│ │ │ │ │ ├── toast
│ │ │ │ │ ├── IPlayerToastService.kt
│ │ │ │ │ ├── PlayerToastService.kt
│ │ │ │ │ └── PlayerToastServiceOwner.kt
│ │ │ │ │ ├── videoquality
│ │ │ │ │ ├── IPlayerVideoQualityService.kt
│ │ │ │ │ └── PlayerVideoQualityService.kt
│ │ │ │ │ └── volume
│ │ │ │ │ ├── IPlayerVolumeService.kt
│ │ │ │ │ ├── PlayerVolumeService.kt
│ │ │ │ │ └── PlayerVolumeServiceOwner.kt
│ │ │ ├── main
│ │ │ │ └── MainActivity.kt
│ │ │ ├── setting
│ │ │ │ └── SettingActivity.kt
│ │ │ ├── shortvideoV2
│ │ │ │ ├── IAllPlayerStateEndListener.kt
│ │ │ │ ├── IShortVideoPlayerViewCacheRecycler.kt
│ │ │ │ ├── MediaItemContextManager.kt
│ │ │ │ ├── MikuClientManager.java
│ │ │ │ ├── PlayItem.kt
│ │ │ │ ├── PlayItemManager.kt
│ │ │ │ ├── ShortVideoActivityV2.kt
│ │ │ │ ├── ShortVideoHolderV2.kt
│ │ │ │ ├── ShortVideoListAdapterV2.kt
│ │ │ │ ├── ShortVideoPlayerViewCache.kt
│ │ │ │ └── SurfacePlayerViewManager.kt
│ │ │ └── simplelongvideo
│ │ │ │ ├── IVideoHolderClickListener.kt
│ │ │ │ ├── SimpleLongVideoActivity.kt
│ │ │ │ ├── VideoHolder.kt
│ │ │ │ └── VideoListAdapter.kt
│ │ │ └── widget
│ │ │ ├── PlayerBiteRateTextWidget.kt
│ │ │ ├── PlayerBufferingWidget.kt
│ │ │ ├── PlayerDownloadTextWidget.kt
│ │ │ ├── PlayerFPSTextWidget.kt
│ │ │ ├── PlayerFirstFrameWidget.kt
│ │ │ ├── PlayerFullScreenPlayClickWidget.kt
│ │ │ ├── PlayerFullScreenWidget.kt
│ │ │ ├── PlayerPausePlayWidget.kt
│ │ │ ├── PlayerPlayWidget.kt
│ │ │ ├── PlayerProgressTextWidget.kt
│ │ │ ├── PlayerSeekWidget.kt
│ │ │ └── commonplayer
│ │ │ ├── controlwidget
│ │ │ ├── CommonPlayerBackWidget.kt
│ │ │ ├── CommonPlayerBiteRateTextWidget.kt
│ │ │ ├── CommonPlayerCaptureWidget.kt
│ │ │ ├── CommonPlayerDownloadTextWidget.kt
│ │ │ ├── CommonPlayerFPSTextWidget.kt
│ │ │ ├── CommonPlayerFullScreenWidget.kt
│ │ │ ├── CommonPlayerInsetControllerWidget.kt
│ │ │ ├── CommonPlayerMoreSettingWidget.kt
│ │ │ ├── CommonPlayerMuteWidget.kt
│ │ │ ├── CommonPlayerPausePlayWidget.kt
│ │ │ ├── CommonPlayerProgressTextWidget.kt
│ │ │ ├── CommonPlayerSeekWidget.kt
│ │ │ ├── CommonPlayerSelectQualityWidget.kt
│ │ │ ├── CommonPlayerSelectSpeedWidget.kt
│ │ │ ├── CommonPlayerSelectVideoWidget.kt
│ │ │ ├── CommonPlayerStopWidget.kt
│ │ │ └── CommonPlayerSubtitleWidget.kt
│ │ │ └── functionwidget
│ │ │ ├── buffering
│ │ │ └── BufferingFunctionWidget.kt
│ │ │ ├── error
│ │ │ └── ErrorFunctionWidget.kt
│ │ │ ├── setting
│ │ │ └── SettingFunctionWidget.kt
│ │ │ ├── shoot
│ │ │ └── PlayerShootVideoFunctionWidget.kt
│ │ │ ├── speed
│ │ │ ├── SpeedFunctionWidget.kt
│ │ │ └── SpeedListAdapter.kt
│ │ │ ├── subtitle
│ │ │ ├── SubtitleFunctionWidget.kt
│ │ │ ├── SubtitleListAdapter.kt
│ │ │ └── SubtitleListFunctionWidget.kt
│ │ │ ├── videolist
│ │ │ ├── VideoListAdapter.kt
│ │ │ └── VideoListFunctionWidget.kt
│ │ │ ├── videoquality
│ │ │ ├── VideoQualityFunctionWidget.kt
│ │ │ └── VideoQualityListAdapter.kt
│ │ │ └── volume
│ │ │ └── PlayerVolumeFunctionWidget.kt
│ │ └── res
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable
│ │ ├── bplayer_seek_pink__scrubber_horizontal.xml
│ │ ├── ic_launcher_background.xml
│ │ ├── nike.png
│ │ ├── qmedia_ic_back.png
│ │ ├── qmedia_ic_new_vod_back_normal.png
│ │ ├── qmedia_ic_picture_bold.xml
│ │ ├── qmedia_ic_player_back_vector.xml
│ │ ├── qmedia_ic_player_fullscreen_vector.xml
│ │ ├── qmedia_ic_player_replay_vector.xml
│ │ ├── qmedia_ic_player_setting_vector.xml
│ │ ├── qmedia_ic_qcode.png
│ │ ├── qmedia_ic_vod_add.png
│ │ ├── qmedia_ic_vod_search.png
│ │ ├── qmedia_ic_volume_mute.xml
│ │ ├── qmedia_ic_volume_unmute.xml
│ │ ├── qmedia_player_pause_selector.xml
│ │ ├── qmedia_player_pause_vector.xml
│ │ ├── qmedia_player_play_pause_level_list.xml
│ │ ├── qmedia_player_play_selector.xml
│ │ ├── qmedia_player_play_vector.xml
│ │ ├── qmedia_player_replay_selector.xml
│ │ ├── qmedia_player_roundrect_black_alpha30_shape.xml
│ │ ├── qmedia_player_seek_bar_drawable.xml
│ │ ├── qmedia_player_selector_panel_text_purple.xml
│ │ ├── qmedia_player_stop_vector.xml
│ │ └── qmedia_question_link.png
│ │ ├── layout
│ │ ├── activity_double_player.xml
│ │ ├── activity_long_video.xml
│ │ ├── activity_main.xml
│ │ ├── activity_setting.xml
│ │ ├── activity_short_video.xml
│ │ ├── activity_short_video2.xml
│ │ ├── activity_simple_long_video.xml
│ │ ├── control_panel_fullscreen_landscape_normal.xml
│ │ ├── control_panel_halfscreen_landscape_normal.xml
│ │ ├── function_audio_volume.xml
│ │ ├── function_buffering.xml
│ │ ├── function_error.xml
│ │ ├── function_setting.xml
│ │ ├── function_shoot_video.xml
│ │ ├── function_speed_list.xml
│ │ ├── function_subtitle.xml
│ │ ├── function_subtitle_list.xml
│ │ ├── function_video_list.xml
│ │ ├── function_video_quality_list.xml
│ │ ├── holder_common_player_list_item.xml
│ │ ├── holder_common_player_video_list_item.xml
│ │ ├── holder_short_video.xml
│ │ ├── holder_video_item.xml
│ │ ├── player_controller_half_screen.xml
│ │ └── player_controller_short_video_screen.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_qplayer2_launcher2.xml
│ │ └── ic_qplayer2_launcher2_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_qplayer2_launcher2.png
│ │ ├── ic_qplayer2_launcher2_foreground.png
│ │ └── ic_qplayer2_launcher2_round.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_qplayer2_launcher2.png
│ │ ├── ic_qplayer2_launcher2_foreground.png
│ │ └── ic_qplayer2_launcher2_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_qplayer2_launcher2.png
│ │ ├── ic_qplayer2_launcher2_foreground.png
│ │ └── ic_qplayer2_launcher2_round.png
│ │ ├── mipmap-xxhdpi
│ │ ├── common_player_control_panel_shape_shadow_bottom.png
│ │ ├── common_player_control_panel_shape_shadow_top.png
│ │ ├── ic_qplayer2_launcher2.png
│ │ ├── ic_qplayer2_launcher2_foreground.png
│ │ └── ic_qplayer2_launcher2_round.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_qplayer2_launcher2.png
│ │ ├── ic_qplayer2_launcher2_foreground.png
│ │ ├── ic_qplayer2_launcher2_round.png
│ │ └── play.png
│ │ ├── raw
│ │ ├── nike.mp4
│ │ └── qiniu_2023_1080p.mp4
│ │ ├── values-night
│ │ └── themes.xml
│ │ ├── values
│ │ ├── attrs.xml
│ │ ├── colors.xml
│ │ ├── ic_qplayer2_launcher2_background.xml
│ │ ├── strings.xml
│ │ ├── styles.xml
│ │ └── themes.xml
│ │ └── xml
│ │ └── network_security_config.xml
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── key
└── settings.gradle
├── README.md
└── ReleaseNote
├── ReleaseNote-0.0.7.md
├── ReleaseNote-1.0.3.md
├── ReleaseNote-1.1.4.md
├── ReleaseNote-1.2.0.md
├── ReleaseNote-1.2.1.md
├── ReleaseNote-1.2.2.md
├── ReleaseNote-1.2.3.md
├── ReleaseNote-1.2.4.md
├── ReleaseNote-1.3.0.md
├── ReleaseNote-1.3.1.md
├── ReleaseNote-1.3.2.md
├── ReleaseNote-1.3.4.md
├── ReleaseNote-1.4.0.md
├── ReleaseNote-1.4.1.md
├── ReleaseNote-1.4.3.md
└── ReleaseNote-1.5.0.md
/Document/qplayer2-core/html/images/anchor-copy-button.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Document/qplayer2-core/html/images/arrow_down.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Document/qplayer2-core/html/images/copy-icon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Document/qplayer2-core/html/images/copy-successful-icon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Document/qplayer2-core/html/images/footer-go-to-link.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Document/qplayer2-core/html/images/go-to-top-icon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Document/qplayer2-core/html/images/logo-icon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Document/qplayer2-core/html/images/theme-toggle.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Document/qplayer2-core/html/scripts/clipboard.js:
--------------------------------------------------------------------------------
1 | window.addEventListener('load', () => {
2 | document.querySelectorAll('span.copy-icon').forEach(element => {
3 | element.addEventListener('click', (el) => copyElementsContentToClipboard(element));
4 | })
5 |
6 | document.querySelectorAll('span.anchor-icon').forEach(element => {
7 | element.addEventListener('click', (el) => {
8 | if(element.hasAttribute('pointing-to')){
9 | const location = hrefWithoutCurrentlyUsedAnchor() + '#' + element.getAttribute('pointing-to')
10 | copyTextToClipboard(element, location)
11 | }
12 | });
13 | })
14 | })
15 |
16 | const copyElementsContentToClipboard = (element) => {
17 | const selection = window.getSelection();
18 | const range = document.createRange();
19 | range.selectNodeContents(element.parentNode.parentNode);
20 | selection.removeAllRanges();
21 | selection.addRange(range);
22 |
23 | copyAndShowPopup(element, () => selection.removeAllRanges())
24 | }
25 |
26 | const copyTextToClipboard = (element, text) => {
27 | var textarea = document.createElement("textarea");
28 | textarea.textContent = text;
29 | textarea.style.position = "fixed";
30 | document.body.appendChild(textarea);
31 | textarea.select();
32 |
33 | copyAndShowPopup(element, () => document.body.removeChild(textarea))
34 | }
35 |
36 | const copyAndShowPopup = (element, after) => {
37 | try {
38 | document.execCommand('copy');
39 | element.nextElementSibling.classList.add('active-popup');
40 | setTimeout(() => {
41 | element.nextElementSibling.classList.remove('active-popup');
42 | }, 1200);
43 | } catch (e) {
44 | console.error('Failed to write to clipboard:', e)
45 | }
46 | finally {
47 | if(after) after()
48 | }
49 | }
50 |
51 | const hrefWithoutCurrentlyUsedAnchor = () => window.location.href.split('#')[0]
52 |
53 |
--------------------------------------------------------------------------------
/Document/qplayer2-core/html/scripts/navigation-loader.js:
--------------------------------------------------------------------------------
1 | navigationPageText = fetch(pathToRoot + "navigation.html").then(response => response.text())
2 |
3 | displayNavigationFromPage = () => {
4 | navigationPageText.then(data => {
5 | document.getElementById("sideMenu").innerHTML = data;
6 | }).then(() => {
7 | document.querySelectorAll(".overview > a").forEach(link => {
8 | link.setAttribute("href", pathToRoot + link.getAttribute("href"));
9 | })
10 | }).then(() => {
11 | document.querySelectorAll(".sideMenuPart").forEach(nav => {
12 | if (!nav.classList.contains("hidden"))
13 | nav.classList.add("hidden")
14 | })
15 | }).then(() => {
16 | revealNavigationForCurrentPage()
17 | })
18 | document.querySelectorAll('.footer a[href^="#"]').forEach(anchor => {
19 | anchor.addEventListener('click', function (e) {
20 | e.preventDefault();
21 | document.querySelector(this.getAttribute('href')).scrollIntoView({
22 | behavior: 'smooth'
23 | });
24 | });
25 | });
26 | }
27 |
28 | revealNavigationForCurrentPage = () => {
29 | let pageId = document.getElementById("content").attributes["pageIds"].value.toString();
30 | let parts = document.querySelectorAll(".sideMenuPart");
31 | let found = 0;
32 | do {
33 | parts.forEach(part => {
34 | if (part.attributes['pageId'].value.indexOf(pageId) !== -1 && found === 0) {
35 | found = 1;
36 | if (part.classList.contains("hidden")) {
37 | part.classList.remove("hidden");
38 | part.setAttribute('data-active', "");
39 | }
40 | revealParents(part)
41 | }
42 | });
43 | pageId = pageId.substring(0, pageId.lastIndexOf("/"))
44 | } while (pageId.indexOf("/") !== -1 && found === 0)
45 | };
46 | revealParents = (part) => {
47 | if (part.classList.contains("sideMenuPart")) {
48 | if (part.classList.contains("hidden"))
49 | part.classList.remove("hidden");
50 | revealParents(part.parentNode)
51 | }
52 | };
53 |
54 | /*
55 | This is a work-around for safari being IE of our times.
56 | It doesn't fire a DOMContentLoaded, presumabely because eventListener is added after it wants to do it
57 | */
58 | if (document.readyState == 'loading') {
59 | window.addEventListener('DOMContentLoaded', () => {
60 | displayNavigationFromPage()
61 | })
62 | } else {
63 | displayNavigationFromPage()
64 | }
--------------------------------------------------------------------------------
/Document/qplayer2-core/html/scripts/sourceset_dependencies.js:
--------------------------------------------------------------------------------
1 | sourceset_dependencies='{":qplayer2-core:dokkaHtml/androidTestRelease":[],":qplayer2-core:dokkaHtml/debug":[],":qplayer2-core:dokkaHtml/main":[],":qplayer2-core:dokkaHtml/release":[],":qplayer2-core:dokkaHtml/testFixtures":[],":qplayer2-core:dokkaHtml/testFixturesDebug":[],":qplayer2-core:dokkaHtml/testFixturesRelease":[]}'
2 |
--------------------------------------------------------------------------------
/Document/qplayer2-core/html/styles/jetbrains-mono.css:
--------------------------------------------------------------------------------
1 | @font-face{
2 | font-family: 'JetBrains Mono';
3 | src: url('https://raw.githubusercontent.com/JetBrains/JetBrainsMono/master/fonts/web/JetBrainsMono-Regular.eot') format('embedded-opentype'),
4 | url('https://raw.githubusercontent.com/JetBrains/JetBrainsMono/master/fonts/webfonts/JetBrainsMono-Regular.woff2') format('woff2'),
5 | url('https://raw.githubusercontent.com/JetBrains/JetBrainsMono/master/fonts/ttf/JetBrainsMono-Regular.ttf') format('truetype');
6 | font-weight: normal;
7 | font-style: normal;
8 | }
9 |
10 | @font-face{
11 | font-family: 'JetBrains Mono';
12 | src: url('https://raw.githubusercontent.com/JetBrains/JetBrainsMono/master/fonts/web/JetBrainsMono-Bold.eot') format('embedded-opentype'),
13 | url('https://raw.githubusercontent.com/JetBrains/JetBrainsMono/master/fonts/webfonts/JetBrainsMono-Bold.woff2') format('woff2'),
14 | url('https://raw.githubusercontent.com/JetBrains/JetBrainsMono/master/fonts/ttf/JetBrainsMono-Bold.ttf') format('truetype');
15 | font-weight: bold;
16 | font-style: bold;
17 | }
--------------------------------------------------------------------------------
/Document/qplayer2-core/html/styles/logo-styles.css:
--------------------------------------------------------------------------------
1 | .library-name a {
2 | position: relative;
3 | margin-left: 55px;
4 | }
5 |
6 | .library-name a::before {
7 | content: '';
8 | background: url("../images/logo-icon.svg") center no-repeat;
9 | background-size: contain;
10 | position: absolute;
11 | width: 50px;
12 | height: 50px;
13 | top: -18px;
14 | left: -55px;
15 | }
--------------------------------------------------------------------------------
/Document/qplayer2-core/html/styles/prism.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --keyword-color: #07a;
3 | --property-color: #905;
4 | --function-color: #DD4A68;
5 | }
6 |
7 | :root.theme-dark {
8 | --keyword-color: #cc7832;
9 | --property-color: #9876aa;
10 | --function-color: #ffc66d;
11 | }
12 |
13 | code .token {
14 | white-space: pre;
15 | }
16 |
17 | /* PrismJS 1.24.1
18 | https://prismjs.com/download.html#themes=prism&languages=clike+java+javadoclike+kotlin&plugins=keep-markup */
19 | /**
20 | * prism.js default theme for JavaScript, CSS and HTML
21 | * Based on dabblet (http://dabblet.com)
22 | * @author Lea Verou
23 | */
24 |
25 | .token.comment,
26 | .token.prolog,
27 | .token.doctype,
28 | .token.cdata {
29 | color: slategray;
30 | }
31 |
32 | .token.punctuation {
33 | color: #999;
34 | }
35 |
36 | .token.namespace {
37 | opacity: .7;
38 | }
39 |
40 | .token.property,
41 | .token.tag,
42 | .token.boolean,
43 | .token.number,
44 | .token.constant,
45 | .token.symbol,
46 | .token.deleted {
47 | color: var(--property-color);
48 | }
49 |
50 | .token.selector,
51 | .token.attr-name,
52 | .token.string,
53 | .token.char,
54 | .token.builtin,
55 | .token.annotation,
56 | .token.inserted {
57 | color: #690;
58 | }
59 |
60 | .token.operator,
61 | .token.entity,
62 | .token.url,
63 | .language-css .token.string,
64 | .style .token.string {
65 | color: #9a6e3a;
66 | /* This background color was intended by the author of this theme. */
67 | /*background: hsla(0, 0%, 100%, .5);*/
68 | }
69 |
70 | .token.atrule,
71 | .token.attr-value,
72 | .token.keyword {
73 | color: var(--keyword-color);
74 | font-size: inherit; /* to override .keyword */
75 | }
76 |
77 | .token.function,
78 | .token.class-name {
79 | color: var(--function-color);
80 | }
81 |
82 | .token.regex,
83 | .token.important,
84 | .token.variable {
85 | color: #e90;
86 | }
87 |
88 | .token.important,
89 | .token.bold {
90 | font-weight: bold;
91 | }
92 | .token.italic {
93 | font-style: italic;
94 | }
95 |
96 | .token.entity {
97 | cursor: help;
98 | }
99 |
100 | .annotation,.control,.field,.filename,.keyword,.menupath,.property,.string,.value {
101 | color: #27282c;
102 | font-weight: 700;
103 | }
--------------------------------------------------------------------------------
/Document/qplayer2-ext/html/images/anchor-copy-button.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Document/qplayer2-ext/html/images/arrow_down.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Document/qplayer2-ext/html/images/copy-icon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Document/qplayer2-ext/html/images/copy-successful-icon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Document/qplayer2-ext/html/images/footer-go-to-link.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Document/qplayer2-ext/html/images/go-to-top-icon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Document/qplayer2-ext/html/images/logo-icon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Document/qplayer2-ext/html/images/theme-toggle.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Document/qplayer2-ext/html/scripts/clipboard.js:
--------------------------------------------------------------------------------
1 | window.addEventListener('load', () => {
2 | document.querySelectorAll('span.copy-icon').forEach(element => {
3 | element.addEventListener('click', (el) => copyElementsContentToClipboard(element));
4 | })
5 |
6 | document.querySelectorAll('span.anchor-icon').forEach(element => {
7 | element.addEventListener('click', (el) => {
8 | if(element.hasAttribute('pointing-to')){
9 | const location = hrefWithoutCurrentlyUsedAnchor() + '#' + element.getAttribute('pointing-to')
10 | copyTextToClipboard(element, location)
11 | }
12 | });
13 | })
14 | })
15 |
16 | const copyElementsContentToClipboard = (element) => {
17 | const selection = window.getSelection();
18 | const range = document.createRange();
19 | range.selectNodeContents(element.parentNode.parentNode);
20 | selection.removeAllRanges();
21 | selection.addRange(range);
22 |
23 | copyAndShowPopup(element, () => selection.removeAllRanges())
24 | }
25 |
26 | const copyTextToClipboard = (element, text) => {
27 | var textarea = document.createElement("textarea");
28 | textarea.textContent = text;
29 | textarea.style.position = "fixed";
30 | document.body.appendChild(textarea);
31 | textarea.select();
32 |
33 | copyAndShowPopup(element, () => document.body.removeChild(textarea))
34 | }
35 |
36 | const copyAndShowPopup = (element, after) => {
37 | try {
38 | document.execCommand('copy');
39 | element.nextElementSibling.classList.add('active-popup');
40 | setTimeout(() => {
41 | element.nextElementSibling.classList.remove('active-popup');
42 | }, 1200);
43 | } catch (e) {
44 | console.error('Failed to write to clipboard:', e)
45 | }
46 | finally {
47 | if(after) after()
48 | }
49 | }
50 |
51 | const hrefWithoutCurrentlyUsedAnchor = () => window.location.href.split('#')[0]
52 |
53 |
--------------------------------------------------------------------------------
/Document/qplayer2-ext/html/scripts/navigation-loader.js:
--------------------------------------------------------------------------------
1 | navigationPageText = fetch(pathToRoot + "navigation.html").then(response => response.text())
2 |
3 | displayNavigationFromPage = () => {
4 | navigationPageText.then(data => {
5 | document.getElementById("sideMenu").innerHTML = data;
6 | }).then(() => {
7 | document.querySelectorAll(".overview > a").forEach(link => {
8 | link.setAttribute("href", pathToRoot + link.getAttribute("href"));
9 | })
10 | }).then(() => {
11 | document.querySelectorAll(".sideMenuPart").forEach(nav => {
12 | if (!nav.classList.contains("hidden"))
13 | nav.classList.add("hidden")
14 | })
15 | }).then(() => {
16 | revealNavigationForCurrentPage()
17 | })
18 | document.querySelectorAll('.footer a[href^="#"]').forEach(anchor => {
19 | anchor.addEventListener('click', function (e) {
20 | e.preventDefault();
21 | document.querySelector(this.getAttribute('href')).scrollIntoView({
22 | behavior: 'smooth'
23 | });
24 | });
25 | });
26 | }
27 |
28 | revealNavigationForCurrentPage = () => {
29 | let pageId = document.getElementById("content").attributes["pageIds"].value.toString();
30 | let parts = document.querySelectorAll(".sideMenuPart");
31 | let found = 0;
32 | do {
33 | parts.forEach(part => {
34 | if (part.attributes['pageId'].value.indexOf(pageId) !== -1 && found === 0) {
35 | found = 1;
36 | if (part.classList.contains("hidden")) {
37 | part.classList.remove("hidden");
38 | part.setAttribute('data-active', "");
39 | }
40 | revealParents(part)
41 | }
42 | });
43 | pageId = pageId.substring(0, pageId.lastIndexOf("/"))
44 | } while (pageId.indexOf("/") !== -1 && found === 0)
45 | };
46 | revealParents = (part) => {
47 | if (part.classList.contains("sideMenuPart")) {
48 | if (part.classList.contains("hidden"))
49 | part.classList.remove("hidden");
50 | revealParents(part.parentNode)
51 | }
52 | };
53 |
54 | /*
55 | This is a work-around for safari being IE of our times.
56 | It doesn't fire a DOMContentLoaded, presumabely because eventListener is added after it wants to do it
57 | */
58 | if (document.readyState == 'loading') {
59 | window.addEventListener('DOMContentLoaded', () => {
60 | displayNavigationFromPage()
61 | })
62 | } else {
63 | displayNavigationFromPage()
64 | }
--------------------------------------------------------------------------------
/Document/qplayer2-ext/html/scripts/sourceset_dependencies.js:
--------------------------------------------------------------------------------
1 | sourceset_dependencies='{":qplayer2-ext:dokkaHtml/androidTestRelease":[],":qplayer2-ext:dokkaHtml/debug":[],":qplayer2-ext:dokkaHtml/main":[],":qplayer2-ext:dokkaHtml/release":[],":qplayer2-ext:dokkaHtml/testFixtures":[],":qplayer2-ext:dokkaHtml/testFixturesDebug":[],":qplayer2-ext:dokkaHtml/testFixturesRelease":[]}'
2 |
--------------------------------------------------------------------------------
/Document/qplayer2-ext/html/styles/jetbrains-mono.css:
--------------------------------------------------------------------------------
1 | @font-face{
2 | font-family: 'JetBrains Mono';
3 | src: url('https://raw.githubusercontent.com/JetBrains/JetBrainsMono/master/fonts/web/JetBrainsMono-Regular.eot') format('embedded-opentype'),
4 | url('https://raw.githubusercontent.com/JetBrains/JetBrainsMono/master/fonts/webfonts/JetBrainsMono-Regular.woff2') format('woff2'),
5 | url('https://raw.githubusercontent.com/JetBrains/JetBrainsMono/master/fonts/ttf/JetBrainsMono-Regular.ttf') format('truetype');
6 | font-weight: normal;
7 | font-style: normal;
8 | }
9 |
10 | @font-face{
11 | font-family: 'JetBrains Mono';
12 | src: url('https://raw.githubusercontent.com/JetBrains/JetBrainsMono/master/fonts/web/JetBrainsMono-Bold.eot') format('embedded-opentype'),
13 | url('https://raw.githubusercontent.com/JetBrains/JetBrainsMono/master/fonts/webfonts/JetBrainsMono-Bold.woff2') format('woff2'),
14 | url('https://raw.githubusercontent.com/JetBrains/JetBrainsMono/master/fonts/ttf/JetBrainsMono-Bold.ttf') format('truetype');
15 | font-weight: bold;
16 | font-style: bold;
17 | }
--------------------------------------------------------------------------------
/Document/qplayer2-ext/html/styles/logo-styles.css:
--------------------------------------------------------------------------------
1 | .library-name a {
2 | position: relative;
3 | margin-left: 55px;
4 | }
5 |
6 | .library-name a::before {
7 | content: '';
8 | background: url("../images/logo-icon.svg") center no-repeat;
9 | background-size: contain;
10 | position: absolute;
11 | width: 50px;
12 | height: 50px;
13 | top: -18px;
14 | left: -55px;
15 | }
--------------------------------------------------------------------------------
/Document/qplayer2-ext/html/styles/prism.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --keyword-color: #07a;
3 | --property-color: #905;
4 | --function-color: #DD4A68;
5 | }
6 |
7 | :root.theme-dark {
8 | --keyword-color: #cc7832;
9 | --property-color: #9876aa;
10 | --function-color: #ffc66d;
11 | }
12 |
13 | code .token {
14 | white-space: pre;
15 | }
16 |
17 | /* PrismJS 1.24.1
18 | https://prismjs.com/download.html#themes=prism&languages=clike+java+javadoclike+kotlin&plugins=keep-markup */
19 | /**
20 | * prism.js default theme for JavaScript, CSS and HTML
21 | * Based on dabblet (http://dabblet.com)
22 | * @author Lea Verou
23 | */
24 |
25 | .token.comment,
26 | .token.prolog,
27 | .token.doctype,
28 | .token.cdata {
29 | color: slategray;
30 | }
31 |
32 | .token.punctuation {
33 | color: #999;
34 | }
35 |
36 | .token.namespace {
37 | opacity: .7;
38 | }
39 |
40 | .token.property,
41 | .token.tag,
42 | .token.boolean,
43 | .token.number,
44 | .token.constant,
45 | .token.symbol,
46 | .token.deleted {
47 | color: var(--property-color);
48 | }
49 |
50 | .token.selector,
51 | .token.attr-name,
52 | .token.string,
53 | .token.char,
54 | .token.builtin,
55 | .token.annotation,
56 | .token.inserted {
57 | color: #690;
58 | }
59 |
60 | .token.operator,
61 | .token.entity,
62 | .token.url,
63 | .language-css .token.string,
64 | .style .token.string {
65 | color: #9a6e3a;
66 | /* This background color was intended by the author of this theme. */
67 | /*background: hsla(0, 0%, 100%, .5);*/
68 | }
69 |
70 | .token.atrule,
71 | .token.attr-value,
72 | .token.keyword {
73 | color: var(--keyword-color);
74 | font-size: inherit; /* to override .keyword */
75 | }
76 |
77 | .token.function,
78 | .token.class-name {
79 | color: var(--function-color);
80 | }
81 |
82 | .token.regex,
83 | .token.important,
84 | .token.variable {
85 | color: #e90;
86 | }
87 |
88 | .token.important,
89 | .token.bold {
90 | font-weight: bold;
91 | }
92 | .token.italic {
93 | font-style: italic;
94 | }
95 |
96 | .token.entity {
97 | cursor: help;
98 | }
99 |
100 | .annotation,.control,.field,.filename,.keyword,.menupath,.property,.string,.value {
101 | color: #27282c;
102 | font-weight: 700;
103 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea
5 | /.idea/caches
6 | /.idea/libraries
7 | /.idea/modules.xml
8 | /.idea/workspace.xml
9 | /.idea/navEditor.xml
10 | /.idea/assetWizardSettings.xml
11 | .DS_Store
12 | /build
13 | /captures
14 | .externalNativeBuild
15 | .cxx
16 | local.properties
17 |
18 | /app/debug
19 | /app/release
20 | /app/build
21 |
--------------------------------------------------------------------------------
/Qplayer2Demo/.idea/.name:
--------------------------------------------------------------------------------
1 | qplayer2demo
--------------------------------------------------------------------------------
/Qplayer2Demo/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Qplayer2Demo/.idea/jarRepositories.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/Qplayer2Demo/.idea/kotlinc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Qplayer2Demo/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Qplayer2Demo/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/Qplayer2Demo/app/libs/qndroid-miku-delivery-v1.1.2.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pili-engineering/QPlayer2-Android/75eaeade6e54a1e24d8d4c0c8125de2fa272215b/Qplayer2Demo/app/libs/qndroid-miku-delivery-v1.1.2.jar
--------------------------------------------------------------------------------
/Qplayer2Demo/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
21 |
29 |
30 |
31 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/TODO.md:
--------------------------------------------------------------------------------
1 | 1.播放器单例
2 | 全局只有一个播放器,类似Youtube,支持小窗 后台播放
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/ic_qplayer2_launcher2-playstore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pili-engineering/QPlayer2-Android/75eaeade6e54a1e24d8d4c0c8125de2fa272215b/Qplayer2Demo/app/src/main/ic_qplayer2_launcher2-playstore.png
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/application/QPlayerApplication.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.application
2 |
3 | import android.app.Application
4 | import android.content.Context
5 | import androidx.multidex.MultiDex
6 | import com.tencent.bugly.crashreport.CrashReport
7 |
8 | class QPlayerApplication: Application() {
9 |
10 | override fun onCreate() {
11 | super.onCreate()
12 | QPlayerApplicationContext.applicationContext = applicationContext
13 | CrashReport.initCrashReport(applicationContext, "adadee00c2", false);
14 | }
15 |
16 | override fun attachBaseContext(base: Context?) {
17 | super.attachBaseContext(base)
18 | MultiDex.install(this)
19 |
20 | }
21 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/application/QPlayerApplicationContext.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.application
2 |
3 | import android.content.Context
4 |
5 | object QPlayerApplicationContext {
6 |
7 | lateinit var applicationContext: Context
8 |
9 |
10 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/common/system/FileUtils.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.common.system
2 |
3 | import android.content.Context
4 | import androidx.annotation.RawRes
5 | import java.io.File
6 | import java.io.FileOutputStream
7 | import java.io.IOException
8 | import java.io.InputStream
9 | import java.io.OutputStream
10 |
11 | object FileUtils {
12 | fun copyFromResToFile(context: Context, @RawRes resId: Int, fileName: String): String? {
13 |
14 | // 获取 raw 资源中的 InputStream
15 | var inputStream: InputStream? = null
16 | var outputStream: OutputStream? = null
17 |
18 | try {
19 | // 打开 res/raw 中的文件
20 | inputStream = context.resources.openRawResource(resId)
21 |
22 | // 获取 files 目录
23 | val filesDir: File = context.filesDir
24 | val outFile = File(filesDir, fileName)
25 |
26 | // 创建输出流,准备写入文件
27 | outputStream = FileOutputStream(outFile)
28 |
29 | // 复制文件内容
30 | val buffer = ByteArray(1024)
31 | var length: Int
32 | while ((inputStream.read(buffer).also { length = it }) > 0) {
33 | outputStream.write(buffer, 0, length)
34 | }
35 |
36 | outputStream.flush() // 确保所有数据都写入文件
37 | return outFile.absolutePath
38 | } catch (e: IOException) {
39 | e.printStackTrace()
40 | } finally {
41 | // 关闭流
42 | try {
43 | inputStream?.close()
44 | outputStream?.close()
45 | } catch (e: IOException) {
46 | e.printStackTrace()
47 | }
48 | }
49 | return null
50 | }
51 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/common/system/PermissionHelper.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.common.system
2 |
3 | import android.Manifest
4 | import android.app.Activity
5 | import android.content.Context
6 | import android.content.pm.PackageManager
7 | import androidx.core.app.ActivityCompat
8 | import androidx.core.content.PackageManagerCompat
9 |
10 | object PermissionHelper {
11 | fun checkPhotoAlbumPermission(activity: Activity): Boolean {
12 |
13 | val permissions = arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE)
14 |
15 | var result = ActivityCompat.checkSelfPermission(activity, permissions[0])
16 | if (result != PackageManager.PERMISSION_GRANTED) {
17 | ActivityCompat.requestPermissions(activity, permissions, 0)
18 | return false
19 | }
20 | return true
21 | }
22 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/common/system/SystemProperties.java:
--------------------------------------------------------------------------------
1 |
2 | package com.qiniu.qplayer2.common.system;
3 |
4 | import androidx.annotation.NonNull;
5 |
6 |
7 | import com.qiniu.qplayer2.common.type.StringUtils;
8 |
9 | import java.lang.reflect.Method;
10 |
11 | /**
12 | * Helper for {@code android.os.SystemProperties}
13 | *
14 | * @author yrom
15 | */
16 | public class SystemProperties {
17 | private static final Method getStringProperty = getMethod(getClass("android.os.SystemProperties"));
18 |
19 | private static Class> getClass(String name) {
20 | try {
21 | Class> cls = Class.forName(name);
22 | if (cls == null) {
23 | throw new ClassNotFoundException();
24 | }
25 | return cls;
26 | } catch (ClassNotFoundException e) {
27 | try {
28 | return ClassLoader.getSystemClassLoader().loadClass(name);
29 | } catch (ClassNotFoundException e1) {
30 | return null;
31 | }
32 | }
33 | }
34 |
35 | private static Method getMethod(Class> clz) {
36 | if (clz == null) return null;
37 | try {
38 | return clz.getMethod("get", String.class);
39 | } catch (Exception e) {
40 | return null;
41 | }
42 | }
43 |
44 | @NonNull
45 | public static String get(String key) {
46 | if (getStringProperty != null) {
47 | try {
48 | Object value = getStringProperty.invoke(null, key);
49 | if (value == null) {
50 | return StringUtils.EMPTY;
51 | }
52 | return StringUtils.trimToEmpty(value.toString());
53 | } catch (Exception ignored) {
54 | }
55 | }
56 | return StringUtils.EMPTY;
57 | }
58 |
59 | public static String get(String key, String def) {
60 | if (getStringProperty != null) {
61 | try {
62 | String value = (String) getStringProperty.invoke(null, key);
63 | return StringUtils.defaultString(StringUtils.trimToNull(value), def);
64 | } catch (Exception ignored) {
65 | }
66 | }
67 | return def;
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/logic/BasePlayerControlVM.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.logic
2 |
3 | import com.qiniu.qmedia.component.player.QPlayerControlHandler
4 |
5 | abstract class BasePlayerControlVM {
6 |
7 | var playerControlHandler: QPlayerControlHandler? = null
8 | set(value) {
9 | if (value == null) {
10 | onClearPlayerListeners()
11 | } else {
12 | field = value
13 | onInstallPlayerControlHandler(field)
14 | }
15 | }
16 |
17 | abstract fun onInstallPlayerControlHandler(controlHandler: QPlayerControlHandler?)
18 |
19 | abstract fun onClearPlayerListeners()
20 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/logic/BasePlayerRenderVM.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.logic
2 |
3 | import com.qiniu.qmedia.component.player.QPlayerControlHandler
4 | import com.qiniu.qmedia.component.player.QPlayerRenderHandler
5 |
6 | abstract class BasePlayerRenderVM {
7 |
8 | var playerRenderHandler: QPlayerRenderHandler? = null
9 | set(value) {
10 | if (value == null) {
11 | onClearPlayerListeners()
12 | } else {
13 | field = value
14 | onInstallPlayerRenderHandler(field)
15 | }
16 | }
17 |
18 | abstract fun onInstallPlayerRenderHandler(renderHandler: QPlayerRenderHandler?)
19 |
20 | abstract fun onClearPlayerListeners()
21 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/logic/PlayerBiteRateVM.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.logic
2 |
3 | import androidx.lifecycle.MutableLiveData
4 | import com.qiniu.qmedia.component.player.QIPlayerBiteRateListener
5 | import com.qiniu.qmedia.component.player.QPlayerControlHandler
6 |
7 | class PlayerBiteRateVM: QIPlayerBiteRateListener, BasePlayerControlVM() {
8 |
9 | val playerBiteRateLiveData = MutableLiveData()
10 |
11 | val bitRate: Long
12 | public get() = playerControlHandler?.biteRate ?: 0L
13 |
14 |
15 | override fun onBiteRateChanged(biteRate: Long) {
16 | playerBiteRateLiveData.value = biteRate
17 | }
18 |
19 | override fun onInstallPlayerControlHandler(controlHandler: QPlayerControlHandler?) {
20 | controlHandler?.addPlayerBiteRateChangeListener(this)
21 | }
22 |
23 | override fun onClearPlayerListeners() {
24 | playerControlHandler?.removePlayerBiteRateChangeListener(this)
25 |
26 | }
27 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/logic/PlayerBufferingVM.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.logic
2 |
3 | import androidx.lifecycle.MutableLiveData
4 | import com.qiniu.qmedia.component.player.QIPlayerBufferingListener
5 | import com.qiniu.qmedia.component.player.QPlayerControlHandler
6 |
7 | class PlayerBufferingVM: QIPlayerBufferingListener, BasePlayerControlVM() {
8 |
9 | val playerBufferingLiveData = MutableLiveData()
10 |
11 | override fun onBufferingStart() {
12 | playerBufferingLiveData.value = true
13 | }
14 |
15 | override fun onBufferingEnd() {
16 | playerBufferingLiveData.value = false
17 | }
18 |
19 | override fun onInstallPlayerControlHandler(controlHandler: QPlayerControlHandler?) {
20 | controlHandler?.addPlayerBufferingChangeListener(this)
21 | }
22 |
23 | override fun onClearPlayerListeners() {
24 | playerControlHandler?.removePlayerBufferingChangeListener(this)
25 |
26 | }
27 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/logic/PlayerDownloadVM.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.logic
2 |
3 | import androidx.lifecycle.MutableLiveData
4 | import com.qiniu.qmedia.component.player.QIPlayerDownloadListener
5 | import com.qiniu.qmedia.component.player.QPlayerControlHandler
6 |
7 | class PlayerDownloadVM: QIPlayerDownloadListener, BasePlayerControlVM() {
8 | val playerDownloadSpeedLiveData = MutableLiveData()
9 |
10 | val downloadSpeed: Long
11 | public get() = playerControlHandler?.downloadSpeed ?: 0L
12 |
13 | override fun onDownloadChanged(speed: Long, bufferProgress: Long) {
14 | playerDownloadSpeedLiveData.value = speed
15 | }
16 |
17 | override fun onInstallPlayerControlHandler(controlHandler: QPlayerControlHandler?) {
18 | controlHandler?.addPlayerDownloadChangeListener(this)
19 | }
20 |
21 | override fun onClearPlayerListeners() {
22 | playerControlHandler?.removePlayerDownloadChangeListener(this)
23 | }
24 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/logic/PlayerFPSVM.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.logic
2 |
3 | import androidx.lifecycle.MutableLiveData
4 | import com.qiniu.qmedia.component.player.QIPlayerFPSListener
5 | import com.qiniu.qmedia.component.player.QPlayerControlHandler
6 |
7 | class PlayerFPSVM:QIPlayerFPSListener, BasePlayerControlVM() {
8 | val playerFPSLiveData = MutableLiveData()
9 |
10 | val fps: Int
11 | public get() = playerControlHandler?.fps ?: 0
12 |
13 | override fun onFPSChanged(fps: Int) {
14 | playerFPSLiveData.value = fps
15 | }
16 |
17 | override fun onInstallPlayerControlHandler(controlHandler: QPlayerControlHandler?) {
18 | controlHandler?.addPlayerFPSChangeListener(this)
19 | }
20 |
21 | override fun onClearPlayerListeners() {
22 | playerControlHandler?.removePlayerFPSChangeListener(this)
23 |
24 | }
25 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/logic/PlayerFirstFrameVM.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.logic
2 |
3 | import androidx.lifecycle.MutableLiveData
4 | import com.qiniu.qmedia.component.player.QIPlayerRenderListener
5 | import com.qiniu.qmedia.component.player.QPlayerRenderHandler
6 |
7 | class PlayerFirstFrameVM : QIPlayerRenderListener, BasePlayerRenderVM() {
8 | val playerFirstFrameElapsedTimeLiveData = MutableLiveData()
9 |
10 | override fun onFirstFrameRendered(elapsedTime: Long) {
11 | playerFirstFrameElapsedTimeLiveData.value = elapsedTime
12 | }
13 |
14 | override fun onInstallPlayerRenderHandler(renderHandler: QPlayerRenderHandler?) {
15 | playerRenderHandler?.addPlayerRenderListener(this)
16 | }
17 |
18 | override fun onClearPlayerListeners() {
19 | playerRenderHandler?.removePlayerRenderListener(this)
20 | }
21 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/logic/PlayerPausePlayVM.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.logic
2 |
3 | import androidx.lifecycle.MutableLiveData
4 | import com.qiniu.qmedia.component.player.QIPlayerStateChangeListener
5 | import com.qiniu.qmedia.component.player.QPlayerControlHandler
6 | import com.qiniu.qmedia.component.player.QPlayerState
7 |
8 | class PlayerPausePlayVM: QIPlayerStateChangeListener, BasePlayerControlVM() {
9 |
10 | val playerStateLiveData = MutableLiveData()
11 |
12 |
13 |
14 | override fun onStateChanged(state: QPlayerState) {
15 |
16 | playerStateLiveData.value = state
17 | }
18 |
19 | public fun getCurrentPlayerState(): QPlayerState {
20 | return playerControlHandler?.currentPlayerState ?: QPlayerState.NONE
21 | }
22 |
23 | public fun resume() {
24 | playerControlHandler?.resumeRender()
25 | }
26 |
27 | public fun pause() {
28 | playerControlHandler?.pauseRender()
29 | }
30 |
31 | override fun onInstallPlayerControlHandler(controlHandler: QPlayerControlHandler?) {
32 | controlHandler?.addPlayerStateChangeListener(this)
33 | }
34 |
35 | override fun onClearPlayerListeners() {
36 | playerControlHandler?.removePlayerStateChangeListener(this)
37 | }
38 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/logic/PlayerProgressVM.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.logic
2 |
3 | import androidx.lifecycle.MutableLiveData
4 | import com.qiniu.qmedia.component.player.QIPlayerDownloadListener
5 | import com.qiniu.qmedia.component.player.QIPlayerProgressListener
6 | import com.qiniu.qmedia.component.player.QPlayerControlHandler
7 |
8 | class PlayerProgressVM : QIPlayerProgressListener, QIPlayerDownloadListener, BasePlayerControlVM() {
9 | val playerProgressLiveData = MutableLiveData()
10 | val playBufferProgressLiveData = MutableLiveData()
11 |
12 |
13 | public fun getDuration(): Long {
14 | return playerControlHandler?.duration ?: 0L
15 | }
16 |
17 | override fun onProgressChanged(duration: Long, progress: Long) {
18 | playerProgressLiveData.value = progress
19 | }
20 |
21 | override fun onInstallPlayerControlHandler(controlHandler: QPlayerControlHandler?) {
22 | controlHandler?.addPlayerProgressChangeListener(this)
23 | controlHandler?.addPlayerDownloadChangeListener(this)
24 | }
25 |
26 | override fun onClearPlayerListeners() {
27 | playerControlHandler?.removePlayerProgressChangeListener(this)
28 | playerControlHandler?.removePlayerDownloadChangeListener(this)
29 | }
30 |
31 | public fun seek(position: Long) {
32 | playerControlHandler?.seek(position)
33 | }
34 |
35 | override fun onDownloadChanged(speed: Long, bufferProgress: Long) {
36 | playBufferProgressLiveData.value = bufferProgress;
37 | }
38 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/repository/shortvideo/ShortVideoApiService.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.repository.shortvideo
2 |
3 | import io.reactivex.rxjava3.core.Single
4 |
5 |
6 | interface ShortVideoApiService {
7 |
8 | // fun getShortVideoList():Single<>
9 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/repository/shortvideo/UpgradeInfo.java:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.repository.shortvideo;
2 |
3 |
4 | public class UpgradeInfo {
5 | private String mAppID;
6 | private String mVersion;
7 | private String mDescription;
8 | private String mDownloadURL;
9 | private String mCreateTime;
10 |
11 | public void setAppID(String appID) {
12 | this.mAppID = appID;
13 | }
14 |
15 | public void setVersion(String version) {
16 | this.mVersion = version;
17 | }
18 |
19 | public void setDescription(String description) {
20 | this.mDescription = description;
21 | }
22 |
23 | public void setDownloadURL(String downloadURL) {
24 | this.mDownloadURL = downloadURL;
25 | }
26 |
27 | public void setCreateTime(String createTime) {
28 | this.mCreateTime = createTime;
29 | }
30 |
31 | public String getAppID() {
32 | return mAppID;
33 | }
34 |
35 | public String getVersion() {
36 | return mVersion;
37 | }
38 |
39 | public String getDescription() {
40 | return mDescription;
41 | }
42 |
43 | public String getDownloadURL() {
44 | return mDownloadURL;
45 | }
46 |
47 | public String getCreateTime() {
48 | return mCreateTime;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/repository/shortvideo/VideoItem.java:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.repository.shortvideo;
2 |
3 | import java.io.Serializable;
4 | import java.text.SimpleDateFormat;
5 | import java.util.Date;
6 |
7 |
8 |
9 | public class VideoItem implements Serializable {
10 | private String mName;
11 | private String mSize;
12 | private String mTime;
13 | private String mVideoPath;
14 |
15 | private String mProxyVideoPath;
16 | private String mCoverPath;
17 |
18 | public static final String VIDEO_PATH_PREFIX = "http://demo-videos.qnsdk.com/";
19 | public static final String COVER_PATH_PREFIX = "http://demo-videos.qnsdk.com/snapshoot/";
20 | public static final String COVER_PATH_SUFFIX = ".jpg";
21 |
22 |
23 | public void setName(String name) {
24 | this.mVideoPath = VIDEO_PATH_PREFIX + name;
25 | this.mName = getVideoName(name);
26 | this.mCoverPath = COVER_PATH_PREFIX + mName + COVER_PATH_SUFFIX;
27 | }
28 |
29 | public void setSize(String size) {
30 | this.mSize = size;
31 | }
32 |
33 | public void setTime(String time) {
34 | time = time.substring(0, 13);
35 | mTime = stampToDate(time);
36 | }
37 |
38 | public void setVideoPath(String name) {
39 | this.mVideoPath = VIDEO_PATH_PREFIX + name;
40 | this.mName = getVideoName(name);
41 | }
42 |
43 | public String getName() {
44 | return mName;
45 | }
46 |
47 | public String getSize() {
48 | return mSize;
49 | }
50 |
51 | public String getTime() {
52 | return mTime;
53 | }
54 |
55 | public String getVideoPath() {
56 | return mVideoPath;
57 | }
58 |
59 | public String getCoverPath() {
60 | return mCoverPath;
61 | }
62 |
63 | private static String stampToDate(String s) {
64 | SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
65 | long lt = new Long(s);
66 | Date date = new Date(lt);
67 | return simpleDateFormat.format(date);
68 | }
69 |
70 | private static String getVideoName(String name) {
71 | int start = name.lastIndexOf("/");
72 | if (start != -1) {
73 | String subString = name.substring(start + 1);
74 | subString = subString.replace(".mp4", "");
75 | return subString;
76 | } else {
77 | return null;
78 | }
79 | }
80 |
81 |
82 | }
83 |
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/tools/AudioFrame.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.tools
2 |
3 | import com.qiniu.qmedia.component.player.QIPlayerAudioDataListener
4 |
5 | class AudioFrame(
6 | val sampleRate: Int,
7 | val channelCount: Int,
8 | val audioFormat: QIPlayerAudioDataListener.QSampleFormat,
9 | val channelLayout: QIPlayerAudioDataListener.QChannelLayout,
10 |
11 | data: ByteArray,
12 | presentationTimeUs: Long
13 | ) : BaseFrame(data, presentationTimeUs)
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/tools/BaseFrame.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.tools
2 |
3 | open class BaseFrame(
4 | val data: ByteArray,
5 | val presentationTimeUs: Long
6 | ) {
7 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/tools/MediaMuxerWrapper.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.tools
2 |
3 | import android.media.MediaCodec
4 | import android.media.MediaMuxer
5 | import android.util.Log
6 | import java.io.IOException
7 | import java.nio.ByteBuffer
8 |
9 | class MediaMuxerWrapper(
10 | private val mAudioEnable: Boolean,
11 | private val mVideoEnable: Boolean,
12 | private val mPath: String
13 | ) {
14 | companion object {
15 | const val INVALID_TRACK_INDEX = -1
16 | const val TAG = "MediaMuxerWrapper"
17 | }
18 |
19 |
20 | private var mIsVideoTrackAdded = false
21 | private var mIsAudioTrackAdded = false
22 |
23 | private var mMediaMuxer: MediaMuxer? = null
24 | private var mIsStart = false
25 | fun init(): Boolean {
26 | Log.d(TAG, "init")
27 | mIsStart = false
28 | try {
29 | mMediaMuxer = MediaMuxer(mPath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4)
30 |
31 | } catch (e: IOException) {
32 | return false
33 | }
34 | return true
35 | }
36 |
37 | fun unint() {
38 | Log.d(TAG, "unint")
39 | if (mIsStart) {
40 | mIsStart = false
41 | mMediaMuxer?.stop()
42 | mMediaMuxer?.release()
43 | }
44 |
45 | }
46 |
47 | @Synchronized
48 | fun addTrackToMediaMuxer(mediaCodec: MediaCodec, type: MediaType): Int {
49 | if (type == MediaType.AUDIO && !mIsAudioTrackAdded) {
50 | mIsAudioTrackAdded = true
51 | Log.d(TAG, "addTrackToMediaMuxer audio")
52 | return mMediaMuxer?.addTrack(mediaCodec.outputFormat) ?: INVALID_TRACK_INDEX
53 | } else if (type == MediaType.VIDEO && !mIsVideoTrackAdded) {
54 | mIsVideoTrackAdded = true
55 | Log.d(TAG, "addTrackToMediaMuxer video")
56 | return mMediaMuxer?.addTrack(mediaCodec.outputFormat) ?: INVALID_TRACK_INDEX
57 | }
58 | return INVALID_TRACK_INDEX
59 | }
60 |
61 | fun writeSampleData(trackIndex: Int, byteBuf: ByteBuffer, bufferInfo: MediaCodec.BufferInfo) {
62 | Log.d(TAG, "writeSampleData index=$trackIndex")
63 | mMediaMuxer?.writeSampleData(trackIndex, byteBuf, bufferInfo)
64 | }
65 |
66 | @Synchronized
67 | fun startIfReady(): Boolean {
68 | val isReady = mAudioEnable == mIsAudioTrackAdded && mVideoEnable && mIsVideoTrackAdded
69 | if (isReady) {
70 | Log.d(TAG, "media muxer start ready")
71 | mIsStart = true
72 | mMediaMuxer?.start()
73 | return true
74 | } else {
75 | Log.d(TAG, "media muxer start but not ready")
76 | }
77 | return false
78 | }
79 |
80 | @Synchronized
81 | fun isStart(): Boolean {
82 | return mIsStart
83 | }
84 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/tools/MediaType.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.tools
2 |
3 | enum class MediaType(val type: Int) {
4 | NONE(0),
5 | VIDEO(1),
6 | AUDIO(2),
7 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/tools/VideoFrame.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.tools
2 |
3 | import com.qiniu.qmedia.component.player.QIPlayerVideoDataListener
4 |
5 | class VideoFrame(val width: Int,
6 | val height: Int,
7 | val videoDataType: QIPlayerVideoDataListener.QVideoDataType,
8 | data: ByteArray,
9 | presentationTimeUs: Long): BaseFrame(data, presentationTimeUs)
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/ui/common/notch/DefaultNotchScreenSupport.java:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.ui.common.notch;
2 |
3 | import android.graphics.Rect;
4 | import android.view.Window;
5 |
6 | import androidx.annotation.NonNull;
7 |
8 | import java.util.ArrayList;
9 | import java.util.List;
10 |
11 | /**
12 | * Created by feifan on 2018/6/15.
13 | * Contacts me:404619986@qq.com
14 | */
15 | class DefaultNotchScreenSupport implements INotchScreenSupport {
16 | @Override
17 | public boolean hasNotchInScreen(@NonNull Window window) {
18 | return false;
19 | }
20 |
21 | @Override
22 | public boolean hasNotchInScreenHardware(@NonNull Window window) {
23 | return hasNotchInScreen(window);
24 | }
25 |
26 | @NonNull
27 | @Override
28 | public List getNotchSize(@NonNull Window window) {
29 | return new ArrayList<>();
30 | }
31 |
32 | @Override
33 | public List getNotchSizeHardware(@NonNull Window window) {
34 | return getNotchSize(window);
35 | }
36 |
37 | @Override
38 | public void setWindowLayoutAroundNotch(@NonNull Window window) {
39 | }
40 |
41 | @Override
42 | public void setWindowLayoutBlockNotch(@NonNull Window window) {
43 | }
44 |
45 | @Override
46 | public void setWindowLayoutNotchDefault(@NonNull Window window) {
47 |
48 | }
49 |
50 | /**
51 | * 折叠屏
52 | * @param window
53 | */
54 | @Override
55 | public void onWindowConfigChanged(@NonNull Window window) {
56 |
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/ui/common/notch/INotchScreenSupport.java:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.ui.common.notch;
2 |
3 | import android.graphics.Rect;
4 | import android.view.Window;
5 |
6 | import androidx.annotation.NonNull;
7 |
8 | import java.util.List;
9 |
10 | /**
11 | * Created by feifan on 2018/6/15.
12 | * Contacts me:404619986@qq.com
13 | */
14 | interface INotchScreenSupport {
15 | boolean hasNotchInScreen(@NonNull Window window);
16 |
17 | /**
18 | * 硬件上屏幕是否存在凹口,{@link #hasNotchInScreen(Window)}用判断当前状态是否存在凹口,
19 | * Android p在调用了{@link #setWindowLayoutBlockNotch(Window)}认为当前状态不存在凹口
20 | *
21 | * @param window window
22 | * @return false, 不存在凹口,true,存在凹口
23 | */
24 | boolean hasNotchInScreenHardware(@NonNull Window window);
25 |
26 | @NonNull
27 | List getNotchSize(@NonNull Window window);
28 |
29 | /**
30 | * 获取硬件上屏幕凹口size,{@link #getNotchSize(Window)},获取当前状态凹口size
31 | * Android p在调用了{@link #setWindowLayoutBlockNotch(Window)}认为当前状态不存在凹口
32 | * 所以获取不到size
33 | *
34 | * @param window window
35 | * @return Rect
36 | */
37 | List getNotchSizeHardware(@NonNull Window window);
38 |
39 | void setWindowLayoutAroundNotch(@NonNull Window window);
40 |
41 | void setWindowLayoutBlockNotch(@NonNull Window window);
42 |
43 | /**
44 | * 重置刘海屏 flag
45 | */
46 | void setWindowLayoutNotchDefault(@NonNull Window window);
47 |
48 | /**
49 | * 折叠屏 config change
50 | * @param window
51 | */
52 | void onWindowConfigChanged(@NonNull Window window);
53 | }
54 |
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/ui/common/notch/MiNotchScreenSupport.java:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.ui.common.notch;
2 |
3 | import android.content.Context;
4 | import android.graphics.Rect;
5 | import android.os.Build;
6 | import android.view.Window;
7 |
8 | import androidx.annotation.NonNull;
9 | import androidx.annotation.RequiresApi;
10 |
11 | import com.qiniu.qplayer2.common.system.SystemProperties;
12 | import com.qiniu.qplayer2.ui.common.statusbar.StatusBarCompat;
13 |
14 | import java.lang.reflect.Method;
15 | import java.util.ArrayList;
16 | import java.util.List;
17 |
18 | /**
19 | * Created by feifan on 2018/6/12.
20 | * Contacts me:404619986@qq.com
21 | * https://dev.mi.com/console/doc/detail?pId=1293
22 | */
23 | final class MiNotchScreenSupport extends DefaultNotchScreenSupport {
24 | //绘制到刘海区域
25 | private static final int FLAG_NOTCH_IMMERSIVE = 0x00000100;
26 | //竖屏绘制到刘海区域
27 | private static final int FLAG_NOTCH_PORTRAIT = 0x00000200;
28 | //横屏绘制刘海区域
29 | private static final int FLAG_NOTCH_LANDSCAPE = 0x00000400;
30 |
31 | @RequiresApi(api = Build.VERSION_CODES.O)
32 | @Override
33 | public boolean hasNotchInScreen(@NonNull Window window) {
34 | try {
35 | return "1".equals(SystemProperties.get("ro.miui.notch", null));
36 | } catch (Exception ignored) {
37 | return false;
38 | }
39 | }
40 |
41 | //小米的状态栏高度会略高于刘海屏的高度,因此通过获取状态栏的高度来间接避开刘海屏,宽度未知,直接返回了屏幕宽度
42 | @NonNull
43 | @RequiresApi(api = Build.VERSION_CODES.O)
44 | @Override
45 | public List getNotchSize(@NonNull Window window) {
46 | List result = new ArrayList<>();
47 |
48 | Context context = window.getContext();
49 | Rect rect = new Rect();
50 | rect.top = 0;
51 | rect.bottom = StatusBarCompat.getStatusBarHeight(context);
52 | rect.left = 0;
53 | rect.right = context.getResources().getDisplayMetrics().widthPixels;
54 | result.add(rect);
55 |
56 | return result;
57 | }
58 |
59 | @RequiresApi(api = Build.VERSION_CODES.O)
60 | @Override
61 | public void setWindowLayoutAroundNotch(@NonNull Window window) {
62 | final int flag = FLAG_NOTCH_IMMERSIVE | FLAG_NOTCH_PORTRAIT | FLAG_NOTCH_LANDSCAPE;
63 | try {
64 | Method method = Window.class.getMethod("addExtraFlags", int.class);
65 | method.invoke(window, flag);
66 | } catch (Exception ignored) {
67 | }
68 | }
69 |
70 | @RequiresApi(api = Build.VERSION_CODES.O)
71 | @Override
72 | public void setWindowLayoutBlockNotch(@NonNull Window window) {
73 | final int flag = FLAG_NOTCH_IMMERSIVE | FLAG_NOTCH_PORTRAIT | FLAG_NOTCH_LANDSCAPE;
74 | try {
75 | Method method = Window.class.getMethod("clearExtraFlags", int.class);
76 | method.invoke(window, flag);
77 | } catch (Exception ignored) {
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/ui/common/notch/OnePLusNotchScreenSupport.java:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.ui.common.notch;
2 |
3 | import android.graphics.Rect;
4 | import android.os.Build;
5 | import android.view.Window;
6 |
7 | import androidx.annotation.NonNull;
8 |
9 |
10 | import com.qiniu.qplayer2.ui.common.statusbar.StatusBarCompat;
11 |
12 | import java.util.ArrayList;
13 | import java.util.List;
14 |
15 | /**
16 | * @author nero
17 | * 一加的当前只有oneplus A6000是刘海屏的,根据型号判断的刘海屏,获取状态栏的高度
18 | */
19 | final class OnePLusNotchScreenSupport extends DefaultNotchScreenSupport {
20 |
21 | private static final String ONE_PLUS_6 = "ONEPLUS A6000";
22 |
23 | @Override
24 | public boolean hasNotchInScreen(@NonNull Window window) {
25 | return ONE_PLUS_6.equals(Build.MODEL);
26 | }
27 |
28 | // 刘海宽度未知,高度以实际状态栏为准
29 | @NonNull
30 | @Override
31 | public List getNotchSize(@NonNull Window window) {
32 | Rect rect = new Rect();
33 | rect.left = 0;
34 | rect.right = 0;
35 | rect.top = 0;
36 | rect.bottom = StatusBarCompat.getStatusBarHeight(window.getContext());
37 |
38 | List result = new ArrayList<>();
39 | result.add(rect);
40 | return result;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/ui/common/notch/OppoNotchScreenSupport.java:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.ui.common.notch;
2 |
3 | import android.content.Context;
4 | import android.graphics.Rect;
5 | import android.os.Build;
6 | import android.util.DisplayMetrics;
7 | import android.view.Window;
8 |
9 | import androidx.annotation.NonNull;
10 | import androidx.annotation.RequiresApi;
11 |
12 | import java.util.ArrayList;
13 | import java.util.List;
14 |
15 | /**
16 | * Created by feifan on 2018/5/15.
17 | * Contacts me:404619986@qq.com
18 | * https://open.oppomobile.com/wiki/doc#id=10159
19 | */
20 | final class OppoNotchScreenSupport extends DefaultNotchScreenSupport {
21 |
22 | @RequiresApi(api = Build.VERSION_CODES.O)
23 | @Override
24 | public boolean hasNotchInScreen(@NonNull Window window) {
25 | try {
26 | return window.getContext().getPackageManager()
27 | .hasSystemFeature("com.oppo.feature.screen.heteromorphism");
28 | } catch (Exception ignored) {
29 | return false;
30 | }
31 | }
32 |
33 | //目前Oppo刘海屏机型尺寸规格都是统一的,显示屏宽度为1080px,高度为2280px,刘海区域宽度为324px, 高度为80px
34 | @NonNull
35 | @RequiresApi(api = Build.VERSION_CODES.O)
36 | @Override
37 | public List getNotchSize(@NonNull Window window) {
38 | List result = new ArrayList<>();
39 | Context context = window.getContext();
40 | Rect rect = new Rect();
41 | DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
42 | final int notchWidth = 324;
43 | final int notchHeight = 80;
44 | rect.left = (displayMetrics.widthPixels - notchWidth) / 2;
45 | rect.right = rect.left + notchWidth;
46 | rect.top = 0;
47 | rect.bottom = notchHeight;
48 | result.add(rect);
49 | return result;
50 | }
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/ui/common/notch/VivoNotchScreenSupport.java:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.ui.common.notch;
2 |
3 | import android.graphics.Rect;
4 | import android.os.Build;
5 | import android.util.DisplayMetrics;
6 | import android.util.TypedValue;
7 | import android.view.Window;
8 |
9 | import androidx.annotation.NonNull;
10 | import androidx.annotation.RequiresApi;
11 |
12 | import java.lang.reflect.Method;
13 | import java.util.ArrayList;
14 | import java.util.List;
15 |
16 | /**
17 | * Created by feifan on 2018/5/15.
18 | * Contacts me:404619986@qq.com
19 | * https://dev.vivo.com.cn/documentCenter/doc/103
20 | */
21 | final class VivoNotchScreenSupport extends DefaultNotchScreenSupport {
22 | private static Class> vivoFtFeature = null;
23 | //表示是否有凹槽
24 | private static final int VIVO_HAS_NOTCH_DISPLAY = 0x00000020;
25 | //表示是否有圆角
26 | private static final int VIVO_HAS_ROUND_DISPLAY = 0x00000008;
27 |
28 | @RequiresApi(api = Build.VERSION_CODES.O)
29 | @Override
30 | public boolean hasNotchInScreen(@NonNull Window window) {
31 | try {
32 | if (vivoFtFeature == null) {
33 | ClassLoader cl = window.getContext().getClassLoader();
34 | vivoFtFeature = cl.loadClass("android.util.FtFeature");
35 | }
36 | Method get = vivoFtFeature.getMethod("isFeatureSupport", int.class);
37 | return (boolean) get.invoke(vivoFtFeature, VIVO_HAS_NOTCH_DISPLAY);
38 | } catch (Exception e) {
39 | return false;
40 | }
41 | }
42 |
43 | //vivo刘海大小固定
44 | @NonNull
45 | @RequiresApi(api = Build.VERSION_CODES.O)
46 | @Override
47 | public List getNotchSize(@NonNull Window window) {
48 | List result = new ArrayList<>();
49 | Rect rect = new Rect();
50 | DisplayMetrics displayMetrics = window.getContext().getResources().getDisplayMetrics();
51 | final int notchWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 100f, displayMetrics);
52 | final int notchHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 27f, displayMetrics);
53 | rect.left = (displayMetrics.widthPixels - notchWidth) / 2;
54 | rect.right = rect.left + notchWidth;
55 | rect.top = 0;
56 | rect.bottom = notchHeight;
57 | result.add(rect);
58 | return result;
59 | }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/ui/common/statusbar/StatusBarCompat.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 BiliBili Inc.
3 | */
4 |
5 | package com.qiniu.qplayer2.ui.common.statusbar;
6 |
7 | import android.annotation.TargetApi;
8 | import android.app.Activity;
9 | import android.content.Context;
10 | import android.content.res.Resources;
11 | import android.content.res.TypedArray;
12 | import android.graphics.Color;
13 | import android.graphics.Point;
14 | import android.os.Build;
15 | import android.view.Display;
16 | import android.view.View;
17 | import android.view.ViewGroup;
18 | import android.view.Window;
19 | import android.view.WindowManager;
20 | import android.widget.FrameLayout;
21 |
22 | import androidx.annotation.ColorInt;
23 | import androidx.annotation.IntDef;
24 | import androidx.core.content.ContextCompat;
25 | import androidx.core.view.ViewCompat;
26 | import androidx.drawerlayout.widget.DrawerLayout;
27 |
28 | import java.lang.annotation.ElementType;
29 | import java.lang.annotation.Retention;
30 | import java.lang.annotation.RetentionPolicy;
31 | import java.lang.annotation.Target;
32 | import java.lang.reflect.Method;
33 | import java.util.regex.Pattern;
34 |
35 | /**
36 | * 状态栏工具类
37 | * 状态栏两种模式(Android 4.4以上)
38 | * 1.沉浸式全屏模式
39 | * 2.状态栏着色模式
40 | */
41 | public class StatusBarCompat {
42 |
43 | /**
44 | * 获取状态栏高度
45 | */
46 | public static int getStatusBarHeight(Context context) {
47 | int result = 0;
48 | int resId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
49 | if (resId > 0) {
50 | result = context.getResources().getDimensionPixelSize(resId);
51 | }
52 | return result;
53 | }
54 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/ui/page/longvideo/LongControlPanelType.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.ui.page.longvideo
2 |
3 | enum class LongControlPanelType(val type: String) {
4 | Normal("normal")
5 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/ui/page/longvideo/LongEnviromentType.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.ui.page.longvideo
2 |
3 | enum class LongEnviromentType(val type: String) {
4 | LONG("Long")
5 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/ui/page/longvideo/LongLogicProvider.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.ui.page.longvideo
2 |
3 | import com.qiniu.qplayer2.common.system.PermissionHelper
4 | import com.qiniu.qplayer2ext.commonplayer.ILogicProvider
5 |
6 | class LongLogicProvider(private val mActivity: LongVideoActivity): ILogicProvider {
7 | fun checkPhotoAlbumPermission(): Boolean {
8 | return PermissionHelper.checkPhotoAlbumPermission(mActivity)
9 | }
10 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/ui/page/longvideo/LongPlayableParams.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.ui.page.longvideo
2 |
3 | import com.qiniu.qmedia.component.player.QMediaModel
4 | import com.qiniu.qplayer2ext.commonplayer.data.DisplayOrientation
5 | import com.qiniu.qplayer2ext.commonplayer.data.CommonPlayableParams
6 |
7 | class LongPlayableParams(
8 | mediaModel: QMediaModel,
9 | controlPanelType: String,
10 | displayOrientation: DisplayOrientation,
11 | environmentType: String,
12 | startPos: Long
13 | ): CommonPlayableParams(mediaModel, controlPanelType, displayOrientation, environmentType, startPos) {
14 |
15 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/ui/page/longvideo/LongVideoParams.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.ui.page.longvideo
2 |
3 | import com.qiniu.qplayer2ext.commonplayer.data.CommonVideoParams
4 |
5 | class LongVideoParams(
6 | val title: String,
7 | id: Long): CommonVideoParams(id) {
8 |
9 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/ui/page/longvideo/service/ServiceOwnerType.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.ui.page.longvideo.service
2 |
3 | enum class ServiceOwnerType(val type: String) {
4 | PLAYER_CONTROL_PANEL_CONTATINER_VISIBLE_SERVICE("PlayerControlPanelContainerVisibleService"),
5 | PLAYER_TOAST_SERVICE("PlayerToastService"),
6 | PLAYER_BUFFERING_SERVICE("PlayerBufferingService"),
7 | PLAYER_NETWORK_SERVICE("PlayerNetworkService"),
8 | PLAYER_PANORAMA_TOUCH_SERVICE("PlayerPanoramaTouchSerivice"),
9 | PLAYER_CAPTURE_SERVICE("PlayerCaptureSerivice"),
10 | PLAYER_VOLUME_SERVICE("PlayerVolumeSerivice"),
11 | PLAYER_SUBTITLE_SERVICE("PlayerSubtitleService")
12 |
13 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/ui/page/longvideo/service/buffering/IPlayerBufferingService.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.ui.page.longvideo.service.buffering
2 |
3 | interface IPlayerBufferingService {
4 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/ui/page/longvideo/service/buffering/PlayerBufferingServiceOwner.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.ui.page.longvideo.service.buffering
2 |
3 | import com.qiniu.qplayer2ext.commonplayer.service.IPlayerServiceOwner
4 | import com.qiniu.qplayer2ext.commonplayer.service.IPlayerServiceManager
5 | import com.qiniu.qplayer2ext.commonplayer.service.PlayerServiceManager
6 | import com.qiniu.qplayer2.ui.page.longvideo.LongLogicProvider
7 | import com.qiniu.qplayer2.ui.page.longvideo.LongPlayableParams
8 | import com.qiniu.qplayer2.ui.page.longvideo.LongVideoParams
9 | import com.qiniu.qplayer2.ui.page.longvideo.service.ServiceOwnerType
10 |
11 | class PlayerBufferingServiceOwner :
12 | IPlayerServiceOwner {
13 |
14 |
15 | override val name: String
16 | get() = ServiceOwnerType.PLAYER_BUFFERING_SERVICE.type
17 |
18 | private val mPlayerBufferingServiceClient: PlayerServiceManager.Client =
19 | PlayerServiceManager.Client()
20 |
21 | override fun start(serviceManager: IPlayerServiceManager) {
22 | serviceManager.bindService(
23 | PlayerServiceManager.ServiceDescriptor.obtain(
24 | PlayerBufferingService::class.java
25 | ), mPlayerBufferingServiceClient
26 | )
27 | }
28 |
29 | override fun stop(serviceManager: IPlayerServiceManager) {
30 | serviceManager.unbindService(
31 | PlayerServiceManager.ServiceDescriptor.obtain(
32 | PlayerBufferingService::class.java
33 | ), mPlayerBufferingServiceClient
34 | )
35 | }
36 |
37 | override fun service(): T {
38 | return mPlayerBufferingServiceClient.service as T
39 | }
40 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/ui/page/longvideo/service/controlpanelcontainervisible/IPlayerControlPanelContainerVisibleService.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.ui.page.longvideo.service.controlpanelcontainervisible
2 |
3 | interface IPlayerControlPanelContainerVisibleService {
4 |
5 | fun setAutoHideEnable(enable: Boolean)
6 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/ui/page/longvideo/service/controlpanelcontainervisible/PlayerControlPanelContainerVisibleServiceOwner.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.ui.page.longvideo.service.controlpanelcontainervisible
2 |
3 | import com.qiniu.qplayer2ext.commonplayer.service.IPlayerServiceOwner
4 | import com.qiniu.qplayer2ext.commonplayer.service.IPlayerServiceManager
5 | import com.qiniu.qplayer2ext.commonplayer.service.PlayerServiceManager
6 | import com.qiniu.qplayer2.ui.page.longvideo.LongLogicProvider
7 | import com.qiniu.qplayer2.ui.page.longvideo.LongPlayableParams
8 | import com.qiniu.qplayer2.ui.page.longvideo.LongVideoParams
9 | import com.qiniu.qplayer2.ui.page.longvideo.service.ServiceOwnerType
10 |
11 | class PlayerControlPanelContainerVisibleServiceOwner
12 | : IPlayerServiceOwner {
13 | override val name: String
14 | get() = ServiceOwnerType.PLAYER_CONTROL_PANEL_CONTATINER_VISIBLE_SERVICE.type
15 |
16 | private val mPlayerControlPanelContainerVisibleServiceClient: PlayerServiceManager.Client =
17 | PlayerServiceManager.Client()
18 |
19 | override fun start(serviceManager: IPlayerServiceManager) {
20 | serviceManager.bindService(PlayerServiceManager.ServiceDescriptor.obtain(
21 | PlayerControlPanelContainerVisibleService::class.java), mPlayerControlPanelContainerVisibleServiceClient)
22 | }
23 |
24 | override fun stop(serviceManager: IPlayerServiceManager) {
25 | serviceManager.unbindService(PlayerServiceManager.ServiceDescriptor.obtain(
26 | PlayerControlPanelContainerVisibleService::class.java), mPlayerControlPanelContainerVisibleServiceClient)
27 | }
28 |
29 | override fun service(): T {
30 | return mPlayerControlPanelContainerVisibleServiceClient.service as T
31 | }
32 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/ui/page/longvideo/service/network/IPlayerNetworkService.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.ui.page.longvideo.service.network
2 |
3 | interface IPlayerNetworkService {
4 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/ui/page/longvideo/service/network/PlayerNetworkServiceOwner.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.ui.page.longvideo.service.network
2 |
3 | import com.qiniu.qplayer2ext.commonplayer.service.IPlayerServiceOwner
4 | import com.qiniu.qplayer2ext.commonplayer.service.IPlayerServiceManager
5 | import com.qiniu.qplayer2ext.commonplayer.service.PlayerServiceManager
6 | import com.qiniu.qplayer2.ui.page.longvideo.LongLogicProvider
7 | import com.qiniu.qplayer2.ui.page.longvideo.LongPlayableParams
8 | import com.qiniu.qplayer2.ui.page.longvideo.LongVideoParams
9 | import com.qiniu.qplayer2.ui.page.longvideo.service.ServiceOwnerType
10 |
11 | class PlayerNetworkServiceOwner:
12 | IPlayerServiceOwner {
13 |
14 |
15 | override val name: String
16 | get() = ServiceOwnerType.PLAYER_NETWORK_SERVICE.type
17 |
18 | private val mPlayerReconnectServiceClient: PlayerServiceManager.Client =
19 | PlayerServiceManager.Client()
20 |
21 | override fun start(serviceManager: IPlayerServiceManager) {
22 | serviceManager.bindService(
23 | PlayerServiceManager.ServiceDescriptor.obtain(
24 | PlayerNetworkService::class.java
25 | ), mPlayerReconnectServiceClient
26 | )
27 | }
28 |
29 | override fun stop(serviceManager: IPlayerServiceManager) {
30 | serviceManager.unbindService(
31 | PlayerServiceManager.ServiceDescriptor.obtain(
32 | PlayerNetworkService::class.java
33 | ), mPlayerReconnectServiceClient
34 | )
35 | }
36 |
37 | override fun service(): T {
38 | return mPlayerReconnectServiceClient.service as T
39 | }
40 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/ui/page/longvideo/service/panorama/IPlayerPanoramaTouchSerivice.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.ui.page.longvideo.service.panorama
2 |
3 | interface IPlayerPanoramaTouchSerivice {
4 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/ui/page/longvideo/service/panorama/PlayerPanoramaTouchSeriviceOwner.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.ui.page.longvideo.service.panorama
2 |
3 | import com.qiniu.qplayer2.ui.page.longvideo.LongLogicProvider
4 | import com.qiniu.qplayer2.ui.page.longvideo.LongPlayableParams
5 | import com.qiniu.qplayer2.ui.page.longvideo.LongVideoParams
6 | import com.qiniu.qplayer2.ui.page.longvideo.service.ServiceOwnerType
7 | import com.qiniu.qplayer2ext.commonplayer.service.IPlayerServiceOwner
8 | import com.qiniu.qplayer2ext.commonplayer.service.IPlayerServiceManager
9 | import com.qiniu.qplayer2ext.commonplayer.service.PlayerServiceManager
10 |
11 | class PlayerPanoramaTouchSeriviceOwner :
12 | IPlayerServiceOwner {
13 |
14 |
15 | override val name: String
16 | get() = ServiceOwnerType.PLAYER_PANORAMA_TOUCH_SERVICE.type
17 |
18 | private val mPlayerPanoramaTouchServiceClient: PlayerServiceManager.Client =
19 | PlayerServiceManager.Client()
20 |
21 | override fun start(serviceManager: IPlayerServiceManager) {
22 | serviceManager.bindService(
23 | PlayerServiceManager.ServiceDescriptor.obtain(
24 | PlayerPanoramaTouchSerivice::class.java
25 | ), mPlayerPanoramaTouchServiceClient
26 | )
27 | }
28 |
29 | override fun stop(serviceManager: IPlayerServiceManager) {
30 | serviceManager.unbindService(
31 | PlayerServiceManager.ServiceDescriptor.obtain(
32 | PlayerPanoramaTouchSerivice::class.java
33 | ), mPlayerPanoramaTouchServiceClient
34 | )
35 | }
36 |
37 | override fun service(): T {
38 | return mPlayerPanoramaTouchServiceClient.service as T
39 | }
40 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/ui/page/longvideo/service/shoot/IPlayerCaptureService.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.ui.page.longvideo.service.shoot
2 |
3 | interface IPlayerCaptureService {
4 |
5 | fun shootVideo()
6 |
7 | fun startRecord()
8 |
9 | fun stopRecord(): Boolean
10 |
11 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/ui/page/longvideo/service/shoot/PlayerShootVideoServiceOwner.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.ui.page.longvideo.service.shoot
2 |
3 | import com.qiniu.qplayer2.ui.page.longvideo.LongLogicProvider
4 | import com.qiniu.qplayer2.ui.page.longvideo.LongPlayableParams
5 | import com.qiniu.qplayer2.ui.page.longvideo.LongVideoParams
6 | import com.qiniu.qplayer2.ui.page.longvideo.service.ServiceOwnerType
7 | import com.qiniu.qplayer2ext.commonplayer.service.IPlayerServiceManager
8 | import com.qiniu.qplayer2ext.commonplayer.service.IPlayerServiceOwner
9 | import com.qiniu.qplayer2ext.commonplayer.service.PlayerServiceManager
10 |
11 | class PlayerShootVideoServiceOwner
12 | : IPlayerServiceOwner {
13 |
14 |
15 | override val name: String
16 | get() = ServiceOwnerType.PLAYER_CAPTURE_SERVICE.type
17 |
18 | private val mPlayerShootVideoServiceClient: PlayerServiceManager.Client =
19 | PlayerServiceManager.Client()
20 |
21 | override fun start(serviceManager: IPlayerServiceManager) {
22 | serviceManager.bindService(
23 | PlayerServiceManager.ServiceDescriptor.obtain(
24 | PlayerCaptureService::class.java
25 | ), mPlayerShootVideoServiceClient
26 | )
27 | }
28 |
29 | override fun stop(serviceManager: IPlayerServiceManager) {
30 | serviceManager.unbindService(
31 | PlayerServiceManager.ServiceDescriptor.obtain(
32 | PlayerCaptureService::class.java
33 | ), mPlayerShootVideoServiceClient
34 | )
35 | }
36 |
37 | override fun service(): T {
38 | return mPlayerShootVideoServiceClient.service as T
39 | }
40 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/ui/page/longvideo/service/subtitle/IPlayerSubtitleService.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.ui.page.longvideo.service.subtitle
2 |
3 | interface IPlayerSubtitleService {
4 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/ui/page/longvideo/service/subtitle/PlayerSubtitleServiceOwner.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.ui.page.longvideo.service.subtitle
2 |
3 | import com.qiniu.qplayer2.ui.page.longvideo.LongLogicProvider
4 | import com.qiniu.qplayer2.ui.page.longvideo.LongPlayableParams
5 | import com.qiniu.qplayer2.ui.page.longvideo.LongVideoParams
6 | import com.qiniu.qplayer2.ui.page.longvideo.service.ServiceOwnerType
7 | import com.qiniu.qplayer2ext.commonplayer.service.IPlayerServiceManager
8 | import com.qiniu.qplayer2ext.commonplayer.service.IPlayerServiceOwner
9 | import com.qiniu.qplayer2ext.commonplayer.service.PlayerServiceManager
10 |
11 | class PlayerSubtitleServiceOwner :
12 | IPlayerServiceOwner {
13 |
14 |
15 | override val name: String
16 | get() = ServiceOwnerType.PLAYER_SUBTITLE_SERVICE.type
17 |
18 | private val mPlayerSubtitleServiceClient: PlayerServiceManager.Client =
19 | PlayerServiceManager.Client()
20 |
21 | override fun start(serviceManager: IPlayerServiceManager) {
22 | serviceManager.bindService(
23 | PlayerServiceManager.ServiceDescriptor.obtain(
24 | PlayerSubtitleService::class.java
25 | ), mPlayerSubtitleServiceClient
26 | )
27 | }
28 |
29 | override fun stop(serviceManager: IPlayerServiceManager) {
30 | serviceManager.unbindService(
31 | PlayerServiceManager.ServiceDescriptor.obtain(
32 | PlayerSubtitleService::class.java
33 | ), mPlayerSubtitleServiceClient
34 | )
35 | }
36 |
37 | override fun service(): T {
38 | return mPlayerSubtitleServiceClient.service as T
39 | }
40 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/ui/page/longvideo/service/toast/IPlayerToastService.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.ui.page.longvideo.service.toast
2 |
3 | interface IPlayerToastService {
4 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/ui/page/longvideo/service/toast/PlayerToastServiceOwner.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.ui.page.longvideo.service.toast
2 |
3 | import com.qiniu.qplayer2ext.commonplayer.service.IPlayerServiceOwner
4 | import com.qiniu.qplayer2ext.commonplayer.service.IPlayerServiceManager
5 | import com.qiniu.qplayer2ext.commonplayer.service.PlayerServiceManager
6 | import com.qiniu.qplayer2.ui.page.longvideo.LongLogicProvider
7 | import com.qiniu.qplayer2.ui.page.longvideo.LongPlayableParams
8 | import com.qiniu.qplayer2.ui.page.longvideo.LongVideoParams
9 | import com.qiniu.qplayer2.ui.page.longvideo.service.ServiceOwnerType
10 |
11 | class PlayerToastServiceOwner :
12 | IPlayerServiceOwner {
13 |
14 | override val name: String
15 | get() = ServiceOwnerType.PLAYER_TOAST_SERVICE.type
16 |
17 | private val mPlayerToastServiceClient: PlayerServiceManager.Client =
18 | PlayerServiceManager.Client()
19 |
20 | override fun start(serviceManager: IPlayerServiceManager) {
21 | serviceManager.bindService(
22 | PlayerServiceManager.ServiceDescriptor.obtain(
23 | PlayerToastService::class.java
24 | ), mPlayerToastServiceClient
25 | )
26 | }
27 |
28 | override fun stop(serviceManager: IPlayerServiceManager) {
29 | serviceManager.unbindService(
30 | PlayerServiceManager.ServiceDescriptor.obtain(
31 | PlayerToastService::class.java
32 | ), mPlayerToastServiceClient
33 | )
34 | }
35 |
36 | override fun service(): T {
37 | return mPlayerToastServiceClient.service as T
38 | }
39 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/ui/page/longvideo/service/videoquality/IPlayerVideoQualityService.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.ui.page.longvideo.service.videoquality
2 |
3 | interface IPlayerVideoQualityService {
4 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/ui/page/longvideo/service/videoquality/PlayerVideoQualityService.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.ui.page.longvideo.service.videoquality
2 |
3 | import com.qiniu.qplayer2ext.commonplayer.CommonPlayerCore
4 | import com.qiniu.qplayer2ext.commonplayer.service.IPlayerService
5 | import com.qiniu.qplayer2.ui.page.longvideo.LongLogicProvider
6 | import com.qiniu.qplayer2.ui.page.longvideo.LongPlayableParams
7 | import com.qiniu.qplayer2.ui.page.longvideo.LongVideoParams
8 |
9 | class PlayerVideoQualityService
10 | : IPlayerService{
11 | override fun onStart() {
12 | TODO("Not yet implemented")
13 | }
14 |
15 | override fun onStop() {
16 | TODO("Not yet implemented")
17 | }
18 |
19 | override fun bindPlayerCore(playerCore: CommonPlayerCore) {
20 | TODO("Not yet implemented")
21 | }
22 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/ui/page/longvideo/service/volume/IPlayerVolumeService.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.ui.page.longvideo.service.volume
2 |
3 | interface IPlayerVolumeService {
4 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/ui/page/longvideo/service/volume/PlayerVolumeServiceOwner.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.ui.page.longvideo.service.volume
2 |
3 | import com.qiniu.qplayer2.ui.page.longvideo.LongLogicProvider
4 | import com.qiniu.qplayer2.ui.page.longvideo.LongPlayableParams
5 | import com.qiniu.qplayer2.ui.page.longvideo.LongVideoParams
6 | import com.qiniu.qplayer2.ui.page.longvideo.service.ServiceOwnerType
7 | import com.qiniu.qplayer2.ui.page.longvideo.service.shoot.PlayerCaptureService
8 | import com.qiniu.qplayer2ext.commonplayer.service.IPlayerServiceManager
9 | import com.qiniu.qplayer2ext.commonplayer.service.IPlayerServiceOwner
10 | import com.qiniu.qplayer2ext.commonplayer.service.PlayerServiceManager
11 |
12 | class PlayerVolumeServiceOwner
13 | : IPlayerServiceOwner {
14 |
15 |
16 | override val name: String
17 | get() = ServiceOwnerType.PLAYER_VOLUME_SERVICE.type
18 |
19 | private val mPlayerVolumeServiceClient: PlayerServiceManager.Client =
20 | PlayerServiceManager.Client()
21 |
22 | override fun start(serviceManager: IPlayerServiceManager) {
23 | serviceManager.bindService(
24 | PlayerServiceManager.ServiceDescriptor.obtain(
25 | PlayerVolumeService::class.java
26 | ), mPlayerVolumeServiceClient
27 | )
28 | }
29 |
30 | override fun stop(serviceManager: IPlayerServiceManager) {
31 | serviceManager.unbindService(
32 | PlayerServiceManager.ServiceDescriptor.obtain(
33 | PlayerCaptureService::class.java
34 | ), mPlayerVolumeServiceClient
35 | )
36 | }
37 |
38 | override fun service(): T {
39 | return mPlayerVolumeServiceClient.service as T
40 | }
41 | }
--------------------------------------------------------------------------------
/Qplayer2Demo/app/src/main/java/com/qiniu/qplayer2/ui/page/main/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.qiniu.qplayer2.ui.page.main
2 |
3 | import android.annotation.SuppressLint
4 | import android.content.Intent
5 | import android.os.Bundle
6 | import android.widget.Button
7 | import android.widget.TextView
8 | import androidx.appcompat.app.AppCompatActivity
9 | import com.qiniu.qplayer2.BuildConfig
10 | import com.qiniu.qplayer2.R
11 | import com.qiniu.qplayer2.ui.page.doubleplayer.DoublePlayerActivity
12 | import com.qiniu.qplayer2.ui.page.longvideo.LongVideoActivity
13 | import com.qiniu.qplayer2.ui.page.simplelongvideo.SimpleLongVideoActivity
14 | import com.qiniu.qplayer2.ui.page.setting.SettingActivity
15 | import com.qiniu.qplayer2.ui.page.shortvideoV2.ShortVideoActivityV2
16 |
17 | class MainActivity : AppCompatActivity() {
18 | @SuppressLint("SetTextI18n")
19 | override fun onCreate(savedInstanceState: Bundle?) {
20 | super.onCreate(savedInstanceState)
21 | setContentView(R.layout.activity_main)
22 |
23 | findViewById