Commit c54ab7cb authored by Tommy Steimel's avatar Tommy Steimel Committed by Commit Bot

Show audio controls when video tag has only audio track

This CL makes CSS and structural changes to audio-track-only videos to
make the controls look like audio controls. This solves an issue where
the controls are not visible/usable on MediaDocument for audio files,
since MediaDocument uses a video tag with an audio source.

This change only applies for modern media controls.

Bug: 811377
Change-Id: Ic73f65585c19047dec1d5904b50c7c4be496c5f5
Reviewed-on: https://chromium-review.googlesource.com/917610
Commit-Queue: Tommy Steimel <steimel@chromium.org>
Reviewed-by: default avatarMounir Lamouri <mlamouri@chromium.org>
Cr-Commit-Position: refs/heads/master@{#537195}
parent 91fe7113
<!DOCTYPE html>
<html>
<title>Test video tag with only audio looks like audio tag</title>
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<script src="../../media-controls.js"></script>
<video id="with-video" controls preload=metadata>
<source src="../../content/60_sec_video.webm" />
</video>
<video id="with-audio" controls preload=metadata>
<source src="../../content/test.oga" />
</video>
<script>
async_test(t => {
let videoWithVideo = document.getElementById('with-video');
let videoWithAudio = document.getElementById('with-audio');
const videoURL = '../../content/60_sec_video.webm';
const audioURL = '../../content/test.oga';
let completedTests = 0;
videoWithVideo.onloadedmetadata = t.step_func(() => {
// Video with video src should look like video controls.
expectLooksLikeVideo(videoWithVideo);
// Changing to an audio src should look like audio controls.
videoWithVideo.onloadedmetadata = t.step_func(() => {
expectLooksLikeAudio(videoWithVideo);
completeTest();
});
loadTrack(videoWithVideo, audioURL);
});
videoWithAudio.onloadedmetadata = t.step_func(() => {
// Video with audio src should look like audio controls.
expectLooksLikeAudio(videoWithAudio);
// Changing to a video src should look like video controls.
videoWithAudio.onloadedmetadata = t.step_func(() => {
expectLooksLikeVideo(videoWithAudio);
completeTest();
});
loadTrack(videoWithAudio, videoURL);
});
// Wait until both video tags have been tested.
function completeTest() {
if (++completedTests == 2) {
t.done();
}
}
// Change the src type.
function loadTrack(video, track) {
let source = video.firstElementChild;
source.setAttribute('src', track);
video.load();
}
function expectLooksLikeVideo(video) {
// The media controls should not have the "audio" class set.
assert_false(mediaControls(video).classList.contains('audio-only'));
// The buttons should be children of the media button panel.
assert_equals(muteButton(video).parentElement.getAttribute('pseudo'), '-internal-media-controls-button-panel');
}
function expectLooksLikeAudio(video) {
// The media controls should have the "audio" class set.
assert_true(mediaControls(video).classList.contains('audio-only'));
// The buttons should be children of the main panel.
assert_equals(muteButton(video).parentElement.getAttribute('pseudo'), '-webkit-media-controls-panel');
}
});
</script>
</html>
...@@ -16,6 +16,14 @@ function isControlVisible(control) { ...@@ -16,6 +16,14 @@ function isControlVisible(control) {
return (display != "none" && visibility == "visible"); return (display != "none" && visibility == "visible");
} }
function mediaControls(videoElement) {
var controlID = '-webkit-media-controls';
var element = mediaControlsElement(window.internals.shadowRoot(videoElement).firstChild, controlID);
if (!element)
throw 'Failed to find media controls';
return element;
}
function castButton(videoElement) { function castButton(videoElement) {
var controlID = '-internal-media-controls-cast-button'; var controlID = '-internal-media-controls-cast-button';
var button = mediaControlsElement(window.internals.shadowRoot(videoElement).firstChild, controlID); var button = mediaControlsElement(window.internals.shadowRoot(videoElement).firstChild, controlID);
...@@ -215,8 +223,9 @@ function timelineThumb(videoElement) { ...@@ -215,8 +223,9 @@ function timelineThumb(videoElement) {
} }
function timelineThumbCurrentTime(videoElement) { function timelineThumbCurrentTime(videoElement) {
const controlID = '-internal-media-controls-thumb-current-time';
const timeline = timelineElement(videoElement); const timeline = timelineElement(videoElement);
const thumb = window.internals.shadowRoot(timeline).getElementById('thumb-current-time'); const thumb = mediaControlsElement(window.internals.shadowRoot(timeline).firstChild, controlID);
if (!thumb) if (!thumb)
throw 'Failed to find timeline current time'; throw 'Failed to find timeline current time';
return thumb; return thumb;
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "modules/media_controls/MediaControlsImpl.h" #include "modules/media_controls/MediaControlsImpl.h"
#include "bindings/core/v8/ExceptionState.h" #include "bindings/core/v8/ExceptionState.h"
#include "bindings/core/v8/string_or_trusted_html.h"
#include "core/css/CSSStyleDeclaration.h" #include "core/css/CSSStyleDeclaration.h"
#include "core/dom/MutationObserver.h" #include "core/dom/MutationObserver.h"
#include "core/dom/MutationObserverInit.h" #include "core/dom/MutationObserverInit.h"
...@@ -125,7 +126,7 @@ constexpr int kModernControlsAudioButtonPadding = 20; ...@@ -125,7 +126,7 @@ constexpr int kModernControlsAudioButtonPadding = 20;
constexpr int kModernControlsVideoButtonPadding = 26; constexpr int kModernControlsVideoButtonPadding = 26;
const char kShowDefaultPosterCSSClass[] = "use-default-poster"; const char kShowDefaultPosterCSSClass[] = "use-default-poster";
const char kActAsAudioControlsCSSClass[] = "audio-only";
const char kScrubbingMessageCSSClass[] = "scrubbing-message"; const char kScrubbingMessageCSSClass[] = "scrubbing-message";
bool ShouldShowFullscreenButton(const HTMLMediaElement& media_element) { bool ShouldShowFullscreenButton(const HTMLMediaElement& media_element) {
...@@ -495,43 +496,23 @@ void MediaControlsImpl::InitializeControls() { ...@@ -495,43 +496,23 @@ void MediaControlsImpl::InitializeControls() {
// If using the modern media controls, the buttons should belong to a // If using the modern media controls, the buttons should belong to a
// seperate button panel. This is because they are displayed in two lines. // seperate button panel. This is because they are displayed in two lines.
Element* button_panel = panel_;
if (IsModern() && MediaElement().IsHTMLVideoElement()) { if (IsModern() && MediaElement().IsHTMLVideoElement()) {
media_button_panel_ = new MediaControlButtonPanelElement(*this);
if (RuntimeEnabledFeatures::DoubleTapToJumpOnVideoEnabled()) { if (RuntimeEnabledFeatures::DoubleTapToJumpOnVideoEnabled()) {
scrubbing_message_ = new MediaControlScrubbingMessageElement(*this); scrubbing_message_ = new MediaControlScrubbingMessageElement(*this);
panel_->AppendChild(scrubbing_message_);
} }
panel_->AppendChild(overlay_play_button_);
media_button_panel_ = new MediaControlButtonPanelElement(*this);
panel_->AppendChild(media_button_panel_);
button_panel = media_button_panel_;
} }
play_button_ = new MediaControlPlayButtonElement(*this); play_button_ = new MediaControlPlayButtonElement(*this);
button_panel->AppendChild(play_button_);
current_time_display_ = new MediaControlCurrentTimeDisplayElement(*this); current_time_display_ = new MediaControlCurrentTimeDisplayElement(*this);
current_time_display_->SetIsWanted(true); current_time_display_->SetIsWanted(true);
button_panel->AppendChild(current_time_display_);
duration_display_ = new MediaControlRemainingTimeDisplayElement(*this); duration_display_ = new MediaControlRemainingTimeDisplayElement(*this);
button_panel->AppendChild(duration_display_);
if (IsModern() && MediaElement().IsHTMLVideoElement()) {
MediaControlElementsHelper::CreateDiv(
"-internal-media-controls-button-spacer", button_panel);
}
timeline_ = new MediaControlTimelineElement(*this); timeline_ = new MediaControlTimelineElement(*this);
panel_->AppendChild(timeline_);
mute_button_ = new MediaControlMuteButtonElement(*this); mute_button_ = new MediaControlMuteButtonElement(*this);
button_panel->AppendChild(mute_button_);
volume_slider_ = new MediaControlVolumeSliderElement(*this); volume_slider_ = new MediaControlVolumeSliderElement(*this);
button_panel->AppendChild(volume_slider_);
if (PreferHiddenVolumeControls(GetDocument())) if (PreferHiddenVolumeControls(GetDocument()))
volume_slider_->SetIsWanted(false); volume_slider_->SetIsWanted(false);
...@@ -540,23 +521,18 @@ void MediaControlsImpl::InitializeControls() { ...@@ -540,23 +521,18 @@ void MediaControlsImpl::InitializeControls() {
MediaElement().IsHTMLVideoElement()) { MediaElement().IsHTMLVideoElement()) {
picture_in_picture_button_ = picture_in_picture_button_ =
new MediaControlPictureInPictureButtonElement(*this); new MediaControlPictureInPictureButtonElement(*this);
button_panel->AppendChild(picture_in_picture_button_);
picture_in_picture_button_->SetIsWanted( picture_in_picture_button_->SetIsWanted(
ShouldShowPictureInPictureButton(MediaElement())); ShouldShowPictureInPictureButton(MediaElement()));
} }
fullscreen_button_ = new MediaControlFullscreenButtonElement(*this);
button_panel->AppendChild(fullscreen_button_);
fullscreen_button_ = new MediaControlFullscreenButtonElement(*this);
download_button_ = new MediaControlDownloadButtonElement(*this); download_button_ = new MediaControlDownloadButtonElement(*this);
button_panel->AppendChild(download_button_);
cast_button_ = new MediaControlCastButtonElement(*this, false); cast_button_ = new MediaControlCastButtonElement(*this, false);
button_panel->AppendChild(cast_button_);
toggle_closed_captions_button_ = toggle_closed_captions_button_ =
new MediaControlToggleClosedCaptionsButtonElement(*this); new MediaControlToggleClosedCaptionsButtonElement(*this);
button_panel->AppendChild(toggle_closed_captions_button_); overflow_menu_ = new MediaControlOverflowMenuButtonElement(*this);
PopulatePanel();
enclosure_->AppendChild(panel_); enclosure_->AppendChild(panel_);
AppendChild(enclosure_); AppendChild(enclosure_);
...@@ -564,8 +540,6 @@ void MediaControlsImpl::InitializeControls() { ...@@ -564,8 +540,6 @@ void MediaControlsImpl::InitializeControls() {
text_track_list_ = new MediaControlTextTrackListElement(*this); text_track_list_ = new MediaControlTextTrackListElement(*this);
AppendChild(text_track_list_); AppendChild(text_track_list_);
overflow_menu_ = new MediaControlOverflowMenuButtonElement(*this);
button_panel->AppendChild(overflow_menu_);
overflow_list_ = new MediaControlOverflowMenuListElement(*this); overflow_list_ = new MediaControlOverflowMenuListElement(*this);
AppendChild(overflow_list_); AppendChild(overflow_list_);
...@@ -598,6 +572,46 @@ void MediaControlsImpl::InitializeControls() { ...@@ -598,6 +572,46 @@ void MediaControlsImpl::InitializeControls() {
UpdateCSSClassFromState(); UpdateCSSClassFromState();
} }
void MediaControlsImpl::PopulatePanel() {
// Clear the panels.
panel_->setInnerHTML(StringOrTrustedHTML::FromString(""));
if (media_button_panel_)
media_button_panel_->setInnerHTML(StringOrTrustedHTML::FromString(""));
Element* button_panel = panel_;
if (IsModern() && MediaElement().IsHTMLVideoElement() &&
!is_acting_as_audio_controls_) {
if (scrubbing_message_)
panel_->AppendChild(scrubbing_message_);
panel_->AppendChild(overlay_play_button_);
panel_->AppendChild(media_button_panel_);
button_panel = media_button_panel_;
}
button_panel->AppendChild(play_button_);
button_panel->AppendChild(current_time_display_);
button_panel->AppendChild(duration_display_);
if (IsModern() && MediaElement().IsHTMLVideoElement()) {
MediaControlElementsHelper::CreateDiv(
"-internal-media-controls-button-spacer", button_panel);
}
panel_->AppendChild(timeline_);
button_panel->AppendChild(mute_button_);
button_panel->AppendChild(volume_slider_);
if (picture_in_picture_button_)
button_panel->AppendChild(picture_in_picture_button_);
button_panel->AppendChild(fullscreen_button_);
button_panel->AppendChild(download_button_);
button_panel->AppendChild(cast_button_);
button_panel->AppendChild(toggle_closed_captions_button_);
button_panel->AppendChild(overflow_menu_);
}
Node::InsertionNotificationRequest MediaControlsImpl::InsertedInto( Node::InsertionNotificationRequest MediaControlsImpl::InsertedInto(
ContainerNode* root) { ContainerNode* root) {
if (!MediaElement().isConnected()) if (!MediaElement().isConnected())
...@@ -633,7 +647,7 @@ void MediaControlsImpl::UpdateCSSClassFromState() { ...@@ -633,7 +647,7 @@ void MediaControlsImpl::UpdateCSSClassFromState() {
StringBuilder builder; StringBuilder builder;
builder.Append(kStateCSSClasses[state]); builder.Append(kStateCSSClasses[state]);
if (MediaElement().IsHTMLVideoElement() && if (MediaElement().IsHTMLVideoElement() && !is_acting_as_audio_controls_ &&
!VideoElement().HasAvailableVideoFrame() && !VideoElement().HasAvailableVideoFrame() &&
VideoElement().PosterImageURL().IsEmpty() && VideoElement().PosterImageURL().IsEmpty() &&
state <= ControlsState::kLoadingMetadata) { state <= ControlsState::kLoadingMetadata) {
...@@ -641,6 +655,11 @@ void MediaControlsImpl::UpdateCSSClassFromState() { ...@@ -641,6 +655,11 @@ void MediaControlsImpl::UpdateCSSClassFromState() {
builder.Append(kShowDefaultPosterCSSClass); builder.Append(kShowDefaultPosterCSSClass);
} }
if (is_acting_as_audio_controls_) {
builder.Append(" ");
builder.Append(kActAsAudioControlsCSSClass);
}
const AtomicString& classes = builder.ToAtomicString(); const AtomicString& classes = builder.ToAtomicString();
if (getAttribute("class") != classes) if (getAttribute("class") != classes)
setAttribute("class", classes); setAttribute("class", classes);
...@@ -1036,17 +1055,17 @@ void MediaControlsImpl::UpdateOverflowMenuWanted() const { ...@@ -1036,17 +1055,17 @@ void MediaControlsImpl::UpdateOverflowMenuWanted() const {
std::make_pair(toggle_closed_captions_button_.Get(), false), std::make_pair(toggle_closed_captions_button_.Get(), false),
}; };
// These are the elements in order of priority that take up vertical room.
MediaControlElementBase* column_elements[] = {
overlay_play_button_.Get(), media_button_panel_.Get(), timeline_.Get(),
};
// Current size of the media controls. // Current size of the media controls.
WebSize controls_size = size_; WebSize controls_size = size_;
// The video controls are more than one row so we need to allocate vertical // The video controls are more than one row so we need to allocate vertical
// room and hide the overlay play button if there is not enough room. // room and hide the overlay play button if there is not enough room.
if (MediaElement().IsHTMLVideoElement()) { if (MediaElement().IsHTMLVideoElement() && !is_acting_as_audio_controls_) {
// These are the elements in order of priority that take up vertical room.
MediaControlElementBase* column_elements[] = {
overlay_play_button_.Get(), media_button_panel_.Get(), timeline_.Get(),
};
controls_size.width -= kModernControlsVideoButtonPadding; controls_size.width -= kModernControlsVideoButtonPadding;
// Allocate vertical room for the column elements. // Allocate vertical room for the column elements.
...@@ -1064,6 +1083,15 @@ void MediaControlsImpl::UpdateOverflowMenuWanted() const { ...@@ -1064,6 +1083,15 @@ void MediaControlsImpl::UpdateOverflowMenuWanted() const {
play_button_->SetIsWanted(!overlay_play_button_->DoesFit()); play_button_->SetIsWanted(!overlay_play_button_->DoesFit());
} else { } else {
controls_size.width -= kModernControlsAudioButtonPadding; controls_size.width -= kModernControlsAudioButtonPadding;
// Undo any IsWanted/DoesFit changes made in the above block if we're
// switching to act as audio controls.
if (is_acting_as_audio_controls_) {
play_button_->SetIsWanted(true);
for (MediaControlElementBase* element : column_elements)
element->SetDoesFit(true);
}
} }
// Go through the elements and if they are sticky allocate them to the panel // Go through the elements and if they are sticky allocate them to the panel
...@@ -1421,6 +1449,13 @@ void MediaControlsImpl::OnLoadedMetadata() { ...@@ -1421,6 +1449,13 @@ void MediaControlsImpl::OnLoadedMetadata() {
// to be changed. // to be changed.
Reset(); Reset();
UpdateCSSClassFromState(); UpdateCSSClassFromState();
if (ShouldActAsAudioControls() != is_acting_as_audio_controls_) {
if (is_acting_as_audio_controls_)
StopActingAsAudioControls();
else
StartActingAsAudioControls();
}
} }
void MediaControlsImpl::OnEnteredFullscreen() { void MediaControlsImpl::OnEnteredFullscreen() {
...@@ -1658,6 +1693,33 @@ void MediaControlsImpl::PositionPopupMenu(Element* popup_menu) { ...@@ -1658,6 +1693,33 @@ void MediaControlsImpl::PositionPopupMenu(Element* popup_menu) {
kImportant, ASSERT_NO_EXCEPTION); kImportant, ASSERT_NO_EXCEPTION);
} }
bool MediaControlsImpl::ShouldActAsAudioControls() const {
// A video element should act like an audio element when it has an audio track
// but no video track.
return IsModern() && MediaElement().IsHTMLVideoElement() &&
MediaElement().HasAudio() && !MediaElement().HasVideo();
}
void MediaControlsImpl::StartActingAsAudioControls() {
DCHECK(ShouldActAsAudioControls());
DCHECK(!is_acting_as_audio_controls_);
is_acting_as_audio_controls_ = true;
PopulatePanel();
UpdateCSSClassFromState();
UpdateOverflowMenuWanted();
}
void MediaControlsImpl::StopActingAsAudioControls() {
DCHECK(!ShouldActAsAudioControls());
DCHECK(is_acting_as_audio_controls_);
is_acting_as_audio_controls_ = false;
PopulatePanel();
UpdateCSSClassFromState();
UpdateOverflowMenuWanted();
}
void MediaControlsImpl::Invalidate(Element* element) { void MediaControlsImpl::Invalidate(Element* element) {
if (!element) if (!element)
return; return;
......
...@@ -208,6 +208,7 @@ class MODULES_EXPORT MediaControlsImpl final : public HTMLDivElement, ...@@ -208,6 +208,7 @@ class MODULES_EXPORT MediaControlsImpl final : public HTMLDivElement,
explicit MediaControlsImpl(HTMLMediaElement&); explicit MediaControlsImpl(HTMLMediaElement&);
void InitializeControls(); void InitializeControls();
void PopulatePanel();
void MakeOpaque(); void MakeOpaque();
void MakeOpaqueFromPointerEvent(); void MakeOpaqueFromPointerEvent();
...@@ -251,6 +252,12 @@ class MODULES_EXPORT MediaControlsImpl final : public HTMLDivElement, ...@@ -251,6 +252,12 @@ class MODULES_EXPORT MediaControlsImpl final : public HTMLDivElement,
// content. // content.
void PositionPopupMenu(Element*); void PositionPopupMenu(Element*);
// When a video element has an audio track but no video track, we modify the
// controls to display like audio controls.
bool ShouldActAsAudioControls() const;
void StartActingAsAudioControls();
void StopActingAsAudioControls();
// Node // Node
bool IsMediaControls() const override { return true; } bool IsMediaControls() const override { return true; }
bool WillRespondToMouseMoveEvents() override { return true; } bool WillRespondToMouseMoveEvents() override { return true; }
...@@ -336,6 +343,8 @@ class MODULES_EXPORT MediaControlsImpl final : public HTMLDivElement, ...@@ -336,6 +343,8 @@ class MODULES_EXPORT MediaControlsImpl final : public HTMLDivElement,
bool pointer_event_did_show_controls_ = false; bool pointer_event_did_show_controls_ = false;
Member<MediaDownloadInProductHelpManager> download_iph_manager_; Member<MediaDownloadInProductHelpManager> download_iph_manager_;
bool is_acting_as_audio_controls_ = false;
}; };
DEFINE_ELEMENT_TYPE_CASTS(MediaControlsImpl, IsMediaControls()); DEFINE_ELEMENT_TYPE_CASTS(MediaControlsImpl, IsMediaControls());
......
...@@ -81,13 +81,12 @@ MediaControlTimelineElement::MediaControlTimelineElement( ...@@ -81,13 +81,12 @@ MediaControlTimelineElement::MediaControlTimelineElement(
Element* thumb = track.getElementById("thumb"); Element* thumb = track.getElementById("thumb");
DCHECK(thumb); DCHECK(thumb);
// The time display should not have a pseudo ID and have a timeline // The time display should have a have a timeline-specific pseudo ID. This
// specific element ID. This is to ensure it does not pick up styles from // is to ensure it does not pick up styles from the current time display.
// the current time display.
current_time_display_ = current_time_display_ =
new MediaControlCurrentTimeDisplayElement(GetMediaControls()); new MediaControlCurrentTimeDisplayElement(GetMediaControls());
current_time_display_->setAttribute("pseudo", ""); current_time_display_->setAttribute(
current_time_display_->setAttribute("id", "thumb-current-time"); "pseudo", "-internal-media-controls-thumb-current-time");
current_time_display_->SetIsWanted(false); current_time_display_->SetIsWanted(false);
thumb->AppendChild(current_time_display_); thumb->AppendChild(current_time_display_);
} }
......
...@@ -103,11 +103,15 @@ video::-internal-media-controls-button-panel { ...@@ -103,11 +103,15 @@ video::-internal-media-controls-button-panel {
box-sizing: border-box; box-sizing: border-box;
} }
audio::-internal-media-controls-button-spacer,
video::-internal-media-controls-button-spacer { video::-internal-media-controls-button-spacer {
flex: 1; flex: 1;
} }
audio::-internal-media-controls-button-spacer,
video::-webkit-media-controls.audio-only [pseudo="-internal-media-controls-button-spacer"] {
display: none;
}
/** /**
* Media Buttons * Media Buttons
*/ */
...@@ -272,7 +276,8 @@ video::-webkit-media-controls-timeline { ...@@ -272,7 +276,8 @@ video::-webkit-media-controls-timeline {
box-sizing: unset !important; box-sizing: unset !important;
} }
audio::-webkit-media-controls-timeline { audio::-webkit-media-controls-timeline,
video::-webkit-media-controls.audio-only [pseudo="-webkit-media-controls-timeline"] {
padding-top: 26px; padding-top: 26px;
padding-bottom: 26px; padding-bottom: 26px;
} }
...@@ -291,6 +296,28 @@ input[pseudo="-webkit-media-controls-timeline" i]::-internal-media-controls-segm ...@@ -291,6 +296,28 @@ input[pseudo="-webkit-media-controls-timeline" i]::-internal-media-controls-segm
position: relative; position: relative;
} }
/* thumb-current-time CSS here instead of in the scoped CSS so we can hide on
* audio-only. */
input[pseudo="-webkit-media-controls-timeline" i]::-internal-media-controls-thumb-current-time {
position: absolute;
height: 16px;
left: 5px;
bottom: 16px;
padding: 4px 12px;
opacity: 0.9;
background: #FFFFFF;
border-radius: 100px;
font-family: Roboto-Regular, Roboto, sans-serif;
font-size: 14px;
color: #000000;
letter-spacing: 0;
text-shadow: 0 0 10px #FFFFFF;
}
video::-webkit-media-controls.audio-only input[pseudo="-webkit-media-controls-timeline"]::-internal-media-controls-thumb-current-time {
display: none;
}
input[pseudo="-webkit-media-controls-timeline" i]::-webkit-slider-thumb { input[pseudo="-webkit-media-controls-timeline" i]::-webkit-slider-thumb {
-webkit-appearance: -internal-media-control; -webkit-appearance: -internal-media-control;
background: rgba(0, 0, 0, .87); background: rgba(0, 0, 0, .87);
...@@ -490,15 +517,19 @@ audio { ...@@ -490,15 +517,19 @@ audio {
height: 54px; height: 54px;
} }
audio::-webkit-media-controls { audio::-webkit-media-controls,
video::-webkit-media-controls.audio-only {
min-width: 240px; min-width: 240px;
min-height: 54px;
} }
audio::-webkit-media-controls-overlay-enclosure { audio::-webkit-media-controls-overlay-enclosure,
video::-webkit-media-controls.audio-only [pseudo="-webkit-media-controls-overlay-enclosure"] {
display: none; display: none;
} }
audio::-webkit-media-controls-enclosure { audio::-webkit-media-controls-enclosure,
video::-webkit-media-controls.audio-only [pseudo="-webkit-media-controls-enclosure"] {
min-height: 54px; min-height: 54px;
max-height: 54px; max-height: 54px;
flex-direction: row; flex-direction: row;
...@@ -507,7 +538,8 @@ audio::-webkit-media-controls-enclosure { ...@@ -507,7 +538,8 @@ audio::-webkit-media-controls-enclosure {
overflow: hidden; overflow: hidden;
} }
audio::-webkit-media-controls-panel { audio::-webkit-media-controls-panel,
video::-webkit-media-controls.audio-only [pseudo="-webkit-media-controls-panel"] {
flex-direction: row; flex-direction: row;
background: none; background: none;
padding: 0 10px; padding: 0 10px;
...@@ -515,30 +547,38 @@ audio::-webkit-media-controls-panel { ...@@ -515,30 +547,38 @@ audio::-webkit-media-controls-panel {
justify-content: flex-start; justify-content: flex-start;
} }
audio::-internal-media-controls-play-button { audio::-internal-media-controls-play-button,
video::-webkit-media-controls.audio-only [pseudo="-internal-media-controls-play-button"] {
display: none; display: none;
} }
audio::-webkit-media-controls-current-time-display { audio::-webkit-media-controls-current-time-display,
video::-webkit-media-controls.audio-only [pseudo="-webkit-media-controls-current-time-display"] {
text-align: right; text-align: right;
margin-left: 5px; margin-left: 5px;
} }
audio::-webkit-media-controls-current-time-display, audio::-webkit-media-controls-current-time-display,
audio::-webkit-media-controls-time-remaining-display { video::-webkit-media-controls.audio-only [pseudo="-webkit-media-controls-current-time-display"],
audio::-webkit-media-controls-time-remaining-display,
video::-webkit-media-controls.audio-only [pseudo="-webkit-media-controls-time-remaining-display"] {
min-width: auto; min-width: auto;
flex: 0; flex: 0;
white-space: nowrap; white-space: nowrap;
} }
audio::-webkit-media-controls-timeline { audio::-webkit-media-controls-timeline,
video::-webkit-media-controls.audio-only [pseudo="-webkit-media-controls-timeline"] {
flex: 1 0 0px; flex: 1 0 0px;
width: 0; width: 0;
} }
audio::-webkit-media-controls-play-button, audio::-webkit-media-controls-play-button,
video::-webkit-media-controls.audio-only [pseudo="-webkit-media-controls-play-button"],
audio::-webkit-media-controls-mute-button, audio::-webkit-media-controls-mute-button,
audio::-internal-media-controls-overflow-button { video::-webkit-media-controls.audio-only [pseudo="-webkit-media-controls-mute-button"],
audio::-internal-media-controls-overflow-button,
video::-webkit-media-controls.audio-only [pseudo="-internal-media-controls-overflow-button"] {
flex: 0 0 32px; flex: 0 0 32px;
} }
...@@ -570,7 +610,8 @@ video::-internal-media-controls-loading-panel { ...@@ -570,7 +610,8 @@ video::-internal-media-controls-loading-panel {
opacity: .5; opacity: .5;
} }
audio::-internal-media-controls-loading-panel { audio::-internal-media-controls-loading-panel,
video::-webkit-media-controls.audio-only [pseudo="-internal-media-controls-loading-panel"] {
display: none; display: none;
} }
......
...@@ -33,19 +33,3 @@ div[pseudo="-internal-track-segment-buffering"]:nth-of-type(3) { ...@@ -33,19 +33,3 @@ div[pseudo="-internal-track-segment-buffering"]:nth-of-type(3) {
#thumb { #thumb {
position: relative; position: relative;
} }
#thumb-current-time {
position: absolute;
height: 16px;
left: 5px;
bottom: 16px;
padding: 4px 12px;
opacity: 0.9;
background: #FFFFFF;
border-radius: 100px;
font-family: Roboto-Regular, Roboto, sans-serif;
font-size: 14px;
color: #000000;
letter-spacing: 0;
text-shadow: 0 0 10px #FFFFFF;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment