browser-mpris2 icon indicating copy to clipboard operation
browser-mpris2 copied to clipboard

Add Support for Youtube Music

Open bashterm opened this issue 6 years ago • 9 comments

bashterm avatar Oct 29 '18 22:10 bashterm

I can do this but I don't know where url is defined in the code or if there can be multiple urls for a single service

bashterm avatar Oct 29 '18 22:10 bashterm

Unfortunately, Youtube Music is not available in my country so I'm afraid I can't do much about this. I can help you though if you have code-related questions.

otommod avatar Oct 29 '18 22:10 otommod

OK. Where does the scan for URL happen? Is it possible to match multiple URLs?

bashterm avatar Oct 29 '18 22:10 bashterm

Look into manifest.json, here's the relevant docs.

otommod avatar Oct 29 '18 22:10 otommod

Youtube Music support would be cool.

The manifest glob should already match the Music url, which is https://music.youtube.com , so something else might be stopping it. I'll have a deeper look after work.

Good extension BTW, thanks! :)

jtmitchell avatar Nov 13 '18 21:11 jtmitchell

Ah, all the classes have different names. Many start with the "ytmusic-". So that is going to fool the code that looks for the buttons.

jtmitchell avatar Nov 13 '18 22:11 jtmitchell

Copy/pasted the HTML from their page below.

The controls are

  • .previous-button
  • .play-pause-button
  • .next-button
  • .volume is the mute button
  • .volume-slider (or #volume-slider) is the volume control
<ytmusic-player-bar slot="player-bar" class="style-scope ytmusic-app" repeat-mode_="NONE" style="--ytmusic-player-bar-fullscreen-progress-bar-inset:20px;">
    
    
    <h2 class="player-bar-a11y-label style-scope ytmusic-player-bar">Player bar</h2>
    <div id="left-controls" class="left-controls style-scope ytmusic-player-bar" style="width: 292px;">
      <div class="left-controls-buttons style-scope ytmusic-player-bar">
        <paper-icon-button class="previous-button style-scope ytmusic-player-bar" icon="miniplayer:skip-previous" role="button" tabindex="0" aria-disabled="false" title="Previous song" aria-label="Previous song"><iron-icon id="icon" class="style-scope paper-icon-button"><svg viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet" focusable="false" class="style-scope iron-icon" style="pointer-events: none; display: block; width: 100%; height: 100%;"><g class="style-scope iron-icon"><path d="M6 6h2v12H6zm3.5 6l8.5 6V6z" class="style-scope iron-icon"></path></g></svg>
    
  </iron-icon><paper-ripple id="ink" center="" class="circle style-scope paper-icon-button">
    

    <div id="background" class="style-scope paper-ripple" style="opacity: 0;"></div>
    <div id="waves" class="style-scope paper-ripple"></div>
  </paper-ripple></paper-icon-button>
        <paper-icon-button id="play-pause-button" class="play-pause-button style-scope ytmusic-player-bar" role="button" tabindex="0" aria-disabled="false" title="Play" aria-label="Play"><iron-icon id="icon" class="style-scope paper-icon-button"><svg viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet" focusable="false" class="style-scope iron-icon" style="pointer-events: none; display: block; width: 100%; height: 100%;"><g class="style-scope iron-icon"><path d="M8 5v14l11-7z" class="style-scope iron-icon"></path></g></svg>
    
  </iron-icon><paper-ripple id="ink" center="" class="circle style-scope paper-icon-button">
    

    <div id="background" class="style-scope paper-ripple" style="opacity: 0.00384;"></div>
    <div id="waves" class="style-scope paper-ripple"></div>
  </paper-ripple></paper-icon-button>
        <paper-icon-button class="next-button style-scope ytmusic-player-bar" icon="miniplayer:skip-next" role="button" tabindex="0" aria-disabled="false" title="Next song" aria-label="Next song"><iron-icon id="icon" class="style-scope paper-icon-button"><svg viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet" focusable="false" class="style-scope iron-icon" style="pointer-events: none; display: block; width: 100%; height: 100%;"><g class="style-scope iron-icon"><path d="M6 18l8.5-6L6 6v12zM16 6v12h2V6h-2z" class="style-scope iron-icon"></path></g></svg>
    
  </iron-icon></paper-icon-button>
      </div>
      <span class="time-info style-scope ytmusic-player-bar">0:01 / 4:16</span>
    </div>
    <div class="middle-controls style-scope ytmusic-player-bar">
      <img class="image style-scope ytmusic-player-bar" alt="" draggable="false" src="https://i.ytimg.com/vi/SDTZ7iX4vTQ/hq720.jpg?sqp=-oaymwEXCJADEOEBIAQqCwjVARCqCBh4INgESFo&amp;rs=AMzJL3kYvSxVf5GSitXzCYr6UiZ_lyWgAA">
      <div class="content-info-wrapper style-scope ytmusic-player-bar">
        <yt-formatted-string class="title style-scope ytmusic-player-bar" ellipsis-truncate="" title="Pumped Up Kicks">Pumped Up Kicks</yt-formatted-string>
        <span class="byline-wrapper style-scope ytmusic-player-bar">
          <div id="badges" class="style-scope ytmusic-player-bar"></div>
          <span class="advertisement style-scope ytmusic-player-bar" hidden="">Ad</span>
          <span class="subtitle style-scope ytmusic-player-bar">
            
              <yt-formatted-string class="byline style-scope ytmusic-player-bar complex-string" ellipsis-truncate="" title="Foster the People" has-link-only_=""><a class="yt-simple-endpoint style-scope yt-formatted-string" spellcheck="false" href="browse/UCIzEvQ6PlJ9XxeDrT9jEBTA">Foster the People</a></yt-formatted-string>
            
              <yt-formatted-string class="byline style-scope ytmusic-player-bar complex-string" ellipsis-truncate="" title="492M views • 4M likes">492M views • 4M likes</yt-formatted-string>
            <template is="dom-repeat" as="text" class="style-scope ytmusic-player-bar"></template>
          </span>
        </span>
      </div>
      <div class="middle-controls-buttons style-scope ytmusic-player-bar">
        <ytmusic-like-button-renderer id="like-button-renderer" class="thumbs style-scope ytmusic-player-bar" show-hover="" like-status="LIKE">
    
    
    <paper-icon-button class="dislike style-scope ytmusic-like-button-renderer" role="button" tabindex="0" aria-disabled="false" title="Dislike" aria-label="Dislike" aria-pressed="false"><iron-icon id="icon" class="style-scope paper-icon-button"><svg viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet" focusable="false" class="style-scope iron-icon" style="pointer-events: none; display: block; width: 100%; height: 100%;"><g class="style-scope iron-icon">
        <path d="M14.9 3H6c-.8 0-1.5.5-1.8 1.2l-3 7.3c-.1.2-.2.4-.2.7v2c0 1.1.9 2 2 2h6.3l-1 4.7v.3c0 .4.2.8.4 1.1.6.7 1.5.7 2.1.1l5.5-5.7c.4-.4.6-.9.6-1.4V5c0-1.1-.9-2-2-2zm-.2 12.6l-3.5 3.6c-.2.2-.5 0-.4-.2l1-4.6H4c-.6 0-1-.5-1-1v-1.1l2.7-6.6c.2-.5.6-.7 1-.7H14c.5 0 1 .5 1 1v8.8c-.1.3-.2.6-.3.8zM19 3h4v12h-4V3z" class="style-scope iron-icon"></path>
      </g></svg>
    
  </iron-icon></paper-icon-button>
    <paper-icon-button class="like style-scope ytmusic-like-button-renderer" role="button" tabindex="0" aria-disabled="false" title="Like" aria-label="Like" aria-pressed="true"><iron-icon id="icon" class="style-scope paper-icon-button"><svg viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet" focusable="false" class="style-scope iron-icon" style="pointer-events: none; display: block; width: 100%; height: 100%;"><g class="style-scope iron-icon">
        <path d="M1 21h4V9H1v12zm22-11c0-1.1-.9-2-2-2h-6.31l.95-4.57.03-.32c0-.41-.17-.79-.44-1.06L14.17 1 7.59 7.59C7.22 7.95 7 8.45 7 9v10c0 1.1.9 2 2 2h9c.83 0 1.54-.5 1.84-1.22l3.02-7.05c.09-.23.14-.47.14-.73v-1.91l-.01-.01L23 10z" class="style-scope iron-icon"></path>
      </g></svg>
    
  </iron-icon></paper-icon-button>
  </ytmusic-like-button-renderer>
        
          <ytmusic-menu-renderer class="menu style-scope ytmusic-player-bar">
    
    
    <div id="top-level-buttons" class="style-scope ytmusic-menu-renderer"></div>
    
      <paper-icon-button id="button" class="dropdown-trigger style-scope ytmusic-menu-renderer" icon="yt-icons:more_vert" role="button" tabindex="0" aria-disabled="false" title="More actions" aria-label="More actions"><iron-icon id="icon" class="style-scope paper-icon-button"><svg viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet" focusable="false" class="style-scope iron-icon" style="pointer-events: none; display: block; width: 100%; height: 100%;"><g class="style-scope iron-icon">
        <path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z" class="style-scope iron-icon"></path>
      </g></svg>
    
  </iron-icon><paper-ripple id="ink" center="" class="circle style-scope paper-icon-button">
    

    <div id="background" class="style-scope paper-ripple" style="opacity: 0.00944;"></div>
    <div id="waves" class="style-scope paper-ripple"></div>
  </paper-ripple></paper-icon-button>
    <template is="dom-if" class="style-scope ytmusic-menu-renderer"></template>
  </ytmusic-menu-renderer>
        <template is="dom-if" class="style-scope ytmusic-player-bar"></template>
      </div>
      <paper-icon-button class="toggle-player-page-button style-scope ytmusic-player-bar" icon="yt-icons:arrow-drop-down" role="button" tabindex="0" aria-disabled="false" title="Open player page" aria-label="Open player page"><iron-icon id="icon" class="style-scope paper-icon-button"><svg viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet" focusable="false" class="style-scope iron-icon" style="pointer-events: none; display: block; width: 100%; height: 100%;"><g class="style-scope iron-icon">
        <path d="M7 10l5 5 5-5z" class="style-scope iron-icon"></path>
      </g></svg>
    
  </iron-icon></paper-icon-button>
    </div>
    <div id="right-controls" class="right-controls style-scope ytmusic-player-bar" style="width: 292px;">
      <paper-slider id="volume-slider" class="volume-slider style-scope ytmusic-player-bar" max="100" min="0" step="5" role="slider" tabindex="0" aria-disabled="false" value="100" aria-valuemin="0" aria-valuemax="100" aria-valuenow="100" title="Volume" aria-label="Volume"><div id="sliderContainer" class="style-scope paper-slider"><div class="bar-container style-scope paper-slider"><paper-progress id="sliderBar" aria-hidden="true" class="style-scope paper-slider" role="progressbar" value="100" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" aria-disabled="false" style="touch-action: none;">
    

    <div id="progressContainer" class="style-scope paper-progress">
      <div id="secondaryProgress" class="style-scope paper-progress" hidden="" style="transform: scaleX(0);"></div>
      <div id="primaryProgress" class="style-scope paper-progress" style="transform: scaleX(1);"></div>
    </div>
  </paper-progress></div><template is="dom-if" class="style-scope paper-slider"></template><div id="sliderKnob" class="slider-knob style-scope paper-slider" style="touch-action: none; left: 100%;"><div class="slider-knob-inner style-scope paper-slider" value="100"></div></div></div><template is="dom-if" class="style-scope paper-slider"></template></paper-slider>
      <div class="right-controls-buttons style-scope ytmusic-player-bar">
        <paper-icon-button class="volume style-scope ytmusic-player-bar" role="button" tabindex="0" aria-disabled="false" title="Mute" aria-label="Mute" aria-pressed="false"><iron-icon id="icon" class="style-scope paper-icon-button"><svg viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet" focusable="false" class="style-scope iron-icon" style="pointer-events: none; display: block; width: 100%; height: 100%;"><g class="style-scope iron-icon"><path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z" class="style-scope iron-icon"></path></g></svg>
    
  </iron-icon></paper-icon-button>
        <paper-icon-button class="repeat style-scope ytmusic-player-bar" role="button" tabindex="0" aria-disabled="false" title="Repeat off" aria-label="Repeat off"><iron-icon id="icon" class="style-scope paper-icon-button"><svg viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet" focusable="false" class="style-scope iron-icon" style="pointer-events: none; display: block; width: 100%; height: 100%;"><g class="style-scope iron-icon">
        <path d="M7 7h10v3l4-4-4-4v3H5v6h2V7zm10 10H7v-3l-4 4 4 4v-3h12v-6h-2v4z" class="style-scope iron-icon"></path>
      </g></svg>
    
  </iron-icon></paper-icon-button>
        <span class="repeat-button-a11y-label style-scope ytmusic-player-bar" aria-live="polite" aria-relevant="text">
          Repeat off
        </span>
        <paper-icon-button class="shuffle style-scope ytmusic-player-bar" icon="yt-icons:shuffle" role="button" tabindex="0" aria-disabled="false" title="Shuffle" aria-label="Shuffle"><iron-icon id="icon" class="style-scope paper-icon-button"><svg viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet" focusable="false" class="style-scope iron-icon" style="pointer-events: none; display: block; width: 100%; height: 100%;"><g class="style-scope iron-icon">
        <path d="M10.59 9.17L5.41 4 4 5.41l5.17 5.17 1.42-1.41zM14.5 4l2.04 2.04L4 18.59 5.41 20 17.96 7.46 20 9.5V4h-5.5zm.33 9.41l-1.41 1.41 3.13 3.13L14.5 20H20v-5.5l-2.04 2.04-3.13-3.13z" class="style-scope iron-icon"></path>
      </g></svg>
    
  </iron-icon></paper-icon-button>
        <paper-icon-button class="expand-button style-scope ytmusic-player-bar" aria-haspopup="true" aria-owns="expanding-menu" icon="yt-icons:arrow-drop-down" role="button" tabindex="0" aria-disabled="false" title="More player controls" aria-label="More player controls"><iron-icon id="icon" class="style-scope paper-icon-button"><svg viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet" focusable="false" class="style-scope iron-icon" style="pointer-events: none; display: block; width: 100%; height: 100%;"><g class="style-scope iron-icon">
        <path d="M7 10l5 5 5-5z" class="style-scope iron-icon"></path>
      </g></svg>
    
  </iron-icon></paper-icon-button>
      </div>
      <ytmusic-player-expanding-menu id="expanding-menu" aria-expanded="false" no-cancel-on-outside-click="" restore-focus-on-close="true" class="style-scope ytmusic-player-bar" role="toolbar" aria-hidden="true" style="outline: none; display: none;">
    
    
    <paper-slider id="expand-volume-slider" class="expand-volume-slider style-scope ytmusic-player-bar" slot="elements" max="100" min="0" step="5" role="slider" tabindex="0" aria-disabled="false" value="100" aria-valuemin="0" aria-valuemax="100" aria-valuenow="100" title="Volume" aria-label="Volume"><div id="sliderContainer" class="style-scope paper-slider"><div class="bar-container style-scope paper-slider"><paper-progress id="sliderBar" aria-hidden="true" class="style-scope paper-slider" role="progressbar" value="100" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" aria-disabled="false" style="touch-action: none;">
    

    <div id="progressContainer" class="style-scope paper-progress">
      <div id="secondaryProgress" class="style-scope paper-progress" hidden="" style="transform: scaleX(0);"></div>
      <div id="primaryProgress" class="style-scope paper-progress" style="transform: scaleX(1);"></div>
    </div>
  </paper-progress></div><template is="dom-if" class="style-scope paper-slider"></template><div id="sliderKnob" class="slider-knob style-scope paper-slider" style="touch-action: none; left: 100%;"><div class="slider-knob-inner style-scope paper-slider" value="100"></div></div></div><template is="dom-if" class="style-scope paper-slider"></template></paper-slider><paper-icon-button id="expand-volume" class="expand-volume style-scope ytmusic-player-bar" slot="elements" role="button" tabindex="0" aria-disabled="false" title="Mute" aria-label="Mute" aria-pressed="false"><iron-icon id="icon" class="style-scope paper-icon-button"><svg viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet" focusable="false" class="style-scope iron-icon" style="pointer-events: none; display: block; width: 100%; height: 100%;"><g class="style-scope iron-icon"><path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z" class="style-scope iron-icon"></path></g></svg>
    
  </iron-icon></paper-icon-button><paper-icon-button id="expand-repeat" class="repeat style-scope ytmusic-player-bar" slot="elements" role="button" tabindex="0" aria-disabled="false" title="Repeat off" aria-label="Repeat off"><iron-icon id="icon" class="style-scope paper-icon-button"><svg viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet" focusable="false" class="style-scope iron-icon" style="pointer-events: none; display: block; width: 100%; height: 100%;"><g class="style-scope iron-icon">
        <path d="M7 7h10v3l4-4-4-4v3H5v6h2V7zm10 10H7v-3l-4 4 4 4v-3h12v-6h-2v4z" class="style-scope iron-icon"></path>
      </g></svg>
    
  </iron-icon></paper-icon-button><paper-icon-button id="expand-shuffle" slot="elements" icon="yt-icons:shuffle" class="style-scope ytmusic-player-bar" role="button" tabindex="0" aria-disabled="false" title="Shuffle" aria-label="Shuffle"><iron-icon id="icon" class="style-scope paper-icon-button"><svg viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet" focusable="false" class="style-scope iron-icon" style="pointer-events: none; display: block; width: 100%; height: 100%;"><g class="style-scope iron-icon">
        <path d="M10.59 9.17L5.41 4 4 5.41l5.17 5.17 1.42-1.41zM14.5 4l2.04 2.04L4 18.59 5.41 20 17.96 7.46 20 9.5V4h-5.5zm.33 9.41l-1.41 1.41 3.13 3.13L14.5 20H20v-5.5l-2.04 2.04-3.13-3.13z" class="style-scope iron-icon"></path>
      </g></svg>
    
  </iron-icon></paper-icon-button>
  </ytmusic-player-expanding-menu>
      <paper-icon-button class="toggle-player-page-button style-scope ytmusic-player-bar" icon="yt-icons:arrow-drop-down" role="button" tabindex="0" aria-disabled="false" aria-label="Open player page"><iron-icon id="icon" class="style-scope paper-icon-button"><svg viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet" focusable="false" class="style-scope iron-icon" style="pointer-events: none; display: block; width: 100%; height: 100%;"><g class="style-scope iron-icon">
        <path d="M7 10l5 5 5-5z" class="style-scope iron-icon"></path>
      </g></svg>
    
  </iron-icon><paper-ripple id="ink" center="" class="circle style-scope paper-icon-button">
    

    <div id="background" class="style-scope paper-ripple" style="opacity: 0;"></div>
    <div id="waves" class="style-scope paper-ripple"></div>
  </paper-ripple></paper-icon-button>
      <paper-icon-button class="exit-fullscreen-button style-scope ytmusic-player-bar" icon="yt-icons:fullscreen_exit" role="button" tabindex="0" aria-disabled="false" title="Exit full screen" aria-label="Exit full screen"><iron-icon id="icon" class="style-scope paper-icon-button"><svg viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet" focusable="false" class="style-scope iron-icon" style="pointer-events: none; display: block; width: 100%; height: 100%;"><g class="style-scope iron-icon">
        <path d="M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z" class="style-scope iron-icon"></path>
      </g></svg>
    
  </iron-icon></paper-icon-button>
    </div>
    <span id="hover-time-info" class="style-scope ytmusic-player-bar" style="left: 0px; display: none;">0:00</span>
    <paper-slider id="progress-bar" class="style-scope ytmusic-player-bar" role="slider" tabindex="0" aria-disabled="false" value="1" aria-valuemin="0" aria-valuemax="256" aria-valuenow="1" title="Seek slider" aria-label="Seek slider" aria-valuetext="0:01 of 4:16"><div id="sliderContainer" class="style-scope paper-slider"><div class="bar-container style-scope paper-slider"><paper-progress id="sliderBar" aria-hidden="true" class="style-scope paper-slider" role="progressbar" value="1" aria-valuenow="1" aria-valuemin="0" aria-valuemax="256" aria-disabled="false" style="touch-action: none;">
    

    <div id="progressContainer" class="style-scope paper-progress">
      <div id="secondaryProgress" class="style-scope paper-progress" style="transform: scaleX(0.476562);"></div>
      <div id="primaryProgress" class="style-scope paper-progress" style="transform: scaleX(0.00390625);"></div>
    </div>
  </paper-progress></div><template is="dom-if" class="style-scope paper-slider"></template><div id="sliderKnob" class="slider-knob style-scope paper-slider" style="touch-action: none; left: 0.390625%;"><div class="slider-knob-inner style-scope paper-slider" value="1"></div></div></div><template is="dom-if" class="style-scope paper-slider"></template></paper-slider>
  </ytmusic-player-bar>

jtmitchell avatar Nov 13 '18 22:11 jtmitchell

I didn't get very far adapting this for music.youtube.com. But for playlists, I did make a bookmarklet to view the selected playlist on the normal youtube domain. javascript:void function(){var t="https://youtube.com"+window.location.pathname+window.location.search;window.location=t}();

jtmitchell avatar Nov 26 '18 20:11 jtmitchell

Not sure if it can help, but https://github.com/MarshallOfSound/Google-Play-Music-Desktop-Player-UNOFFICIAL- has MPRIS support for YouTube Music, maybe the code could be used here.

aldomann avatar May 19 '19 17:05 aldomann