Commit a7ac92b0 authored by Björn Bartels's avatar Björn Bartels
Browse files

Initial commit

parents
Loading
Loading
Loading
Loading
Loading

.gitignore

0 → 100644
+8 −0
Original line number Diff line number Diff line
.project
.buildpath
.settings

_save
temp
/node_modules/
.DS*

README.md

0 → 100644
+21 −0
Original line number Diff line number Diff line
# \<audio-player\>

a basic audio-player (with playlist)

## Install the Polymer-CLI

First, make sure you have the [Polymer CLI](https://www.npmjs.com/package/polymer-cli) and npm (packaged with [Node.js](https://nodejs.org)) installed. Run `npm install` to install your element's dependencies, then run `polymer serve` to serve your element locally.

## Viewing Your Element

```
$ polymer serve
```

## Running Tests

```
$ polymer test
```

Your application is already set up to be tested via [web-component-tester](https://github.com/Polymer/web-component-tester). Run `polymer test` to run your application's test suite locally.

audio-player.js

0 → 100644
+502 −0
Original line number Diff line number Diff line
import {html, PolymerElement} from '@polymer/polymer/polymer-element.js'
import audioPlayer from './src/js/audio-element-player.js'
/**
 * `audio-player`
 * a basic audio-player (with playlist)
 *
 * @customElement
 * @polymer
 * @demo demo/index.html
 */
class AudioPlayer extends PolymerElement {

  static get svgIcons() {
    return html`
      <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="display: none;">
        <symbol id="icon-play" viewBox="0 0 163.861 163.861">
          <path fill="var(--button-icon-fill-color)" d="M34.857 3.613C20.084-4.861 8.107 2.081 8.107 19.106v125.637c0 17.042 11.977 23.975 26.75 15.509L144.67 97.275c14.778-8.477 14.778-22.211 0-30.686L34.857 3.613z"/>
        </symbol>
        <symbol id="icon-pause" viewBox="0 0 438.536 438.536">
          <path fill="var(--button-icon-fill-color)" d="M164.453 0H18.276C13.324 0 9.041 1.807 5.425 5.424 1.808 9.04.001 13.322.001 18.271v401.991c0 4.948 1.807 9.233 5.424 12.847 3.619 3.617 7.902 5.428 12.851 5.428h146.181c4.949 0 9.231-1.811 12.847-5.428 3.617-3.613 5.424-7.898 5.424-12.847V18.271c0-4.952-1.807-9.231-5.428-12.847C173.685 1.807 169.402 0 164.453 0zM433.113 5.424C429.496 1.807 425.215 0 420.267 0H274.086c-4.949 0-9.237 1.807-12.847 5.424-3.621 3.615-5.432 7.898-5.432 12.847v401.991c0 4.948 1.811 9.233 5.432 12.847 3.609 3.617 7.897 5.428 12.847 5.428h146.181c4.948 0 9.229-1.811 12.847-5.428 3.614-3.613 5.421-7.898 5.421-12.847V18.271c-.001-4.952-1.805-9.231-5.422-12.847z"/>
        </symbol>
        <symbol id="icon-stop" viewBox="0 0 360.72 360.72">
          <path fill="var(--button-icon-fill-color)" d="M360.72 352.99a7.726 7.726 0 0 1-7.728 7.727H7.722A7.725 7.725 0 0 1 0 352.99V7.724A7.723 7.723 0 0 1 7.722.003h345.271c4.259 0 7.716 3.458 7.716 7.721V352.99h.011z"/>
        </symbol>
        <symbol id="icon-backward" viewBox="0 0 440.25 440.25">
          <path fill="none" d="M-1-1h582v402H-1z"/>
          <path fill="var(--button-icon-fill-color)" d="M5.427 232.972L208.139 435.68c3.609 3.617 6.655 4.856 9.133 3.713 2.475-1.143 3.712-4.189 3.712-9.137V227.548c.949 2.091 2.187 3.901 3.711 5.424L427.403 435.68c3.618 3.617 6.661 4.856 9.136 3.713 2.474-1.143 3.711-4.189 3.711-9.137V9.994c0-4.948-1.237-7.994-3.711-9.138-2.474-1.14-5.518.1-9.135 3.721L224.696 207.278c-1.521 1.711-2.762 3.524-3.711 5.428V9.994c0-4.948-1.237-7.99-3.712-9.13-2.478-1.144-5.523.092-9.133 3.713L5.428 207.285C1.818 210.902 0 215.186 0 220.132c.002 4.941 1.817 9.223 5.427 12.84z"/>
        </symbol>
        <symbol id="icon-forward" viewBox="0 0 440.25 440.25">
          <path fill="var(--button-icon-fill-color)" d="M434.823 207.279L232.111 4.571c-3.609-3.617-6.655-4.856-9.133-3.713-2.475 1.143-3.712 4.189-3.712 9.137v202.708c-.949-2.091-2.187-3.901-3.711-5.424L12.847 4.571C9.229.954 6.186-.285 3.711.858 1.237 2.001 0 5.047 0 9.995v420.262c0 4.948 1.237 7.994 3.711 9.138 2.474 1.14 5.518-.1 9.135-3.721l202.708-202.701c1.521-1.711 2.762-3.524 3.711-5.428v202.712c0 4.948 1.237 7.991 3.712 9.131 2.478 1.143 5.523-.093 9.133-3.714l202.712-202.708c3.61-3.617 5.428-7.901 5.428-12.847-.002-4.941-1.817-9.223-5.427-12.84z"/>
        </symbol>
        <symbol id="icon-previous" viewBox="0 0 17.802 17.802">
          <path fill="var(--button-icon-fill-color)" d="M15.363.042a.398.398 0 0 0-.424.043L4.163 8.587a.41.41 0 0 0-.153.313c0 .119.059.24.153.314l10.776 8.502a.402.402 0 0 0 .249.086l.175-.039a.395.395 0 0 0 .225-.361V.403a.396.396 0 0 0-.225-.361z"/>
          <path fill="var(--button-icon-fill-color)" d="M5.188.033H2.53c-.172 0-.315.182-.315.401V17.37c0 .221.143.403.315.403h2.657c.174 0 .315-.183.315-.403V.434c.001-.219-.141-.401-.314-.401z"/>
        </symbol>
        <symbol id="icon-next" viewBox="0 0 17.804 17.804">
          <path fill="var(--button-icon-fill-color)" d="M2.44.043a.396.396 0 0 1 .425.044l10.777 8.502a.402.402 0 0 1 .152.312c0 .118-.059.24-.152.314L2.864 17.718a.411.411 0 0 1-.25.086l-.175-.04a.397.397 0 0 1-.223-.362V.403c0-.154.086-.297.224-.36z"/>
          <path fill="var(--button-icon-fill-color)" d="M12.616.034h2.656c.175 0 .316.181.316.399v16.935c0 .222-.142.403-.316.403h-2.656c-.174 0-.316-.182-.316-.403V.434c0-.219.143-.4.316-.4z"/>
        </symbol>
        <symbol id="icon-volume-mute" viewBox="0 0 27.717 27.717">
          <path fill="var(--button-icon-fill-color)" d="M4.637 8.725H0v10.33h4.637l8.766 6.502s1.611 1.346 1.611-.045V2.066c0-1.092-1.418-.025-1.418-.025L4.637 8.725z"/>
          <path fill="var(--button-icon-fill-color)" stroke="var(--button-icon-fill-color)" stroke-width="2" d="M17.491 8.146l7.919 11.713M17.403 19.614l7.925-11.429"/>
        </symbol>
        <symbol id="icon-volume-up" viewBox="0 0 27.717 27.717">
          <path fill="var(--button-icon-fill-color)" d="M4.637 8.725H0v10.33h4.637l8.766 6.502s1.611 1.346 1.611-.045V2.066c0-1.092-1.418-.025-1.418-.025L4.637 8.725zM20.006 6.709a1.18 1.18 0 0 0-1.668 0 1.176 1.176 0 0 0 0 1.666 7.734 7.734 0 0 1 2.273 5.484 7.752 7.752 0 0 1-2.273 5.495 1.184 1.184 0 0 0 0 1.672c.23.23.531.344.836.344.301 0 .602-.113.832-.344a10.107 10.107 0 0 0 2.963-7.167 10.075 10.075 0 0 0-2.963-7.15z"/>
          <path fill="var(--button-icon-fill-color)" d="M23.207 2.994a1.185 1.185 0 0 0-1.676 0 1.19 1.19 0 0 0 0 1.671 12.97 12.97 0 0 1 3.824 9.206 13.038 13.038 0 0 1-3.824 9.25 1.187 1.187 0 0 0 0 1.67 1.193 1.193 0 0 0 1.676 0 15.434 15.434 0 0 0 4.51-10.92c0-3.934-1.514-7.875-4.51-10.877z"/>
        </symbol>
        <symbol id="icon-volume-down" viewBox="0 0 27.717 27.717">
          <path fill="var(--button-icon-fill-color)" d="M4.637 8.725H0v10.33h4.637l8.766 6.502s1.611 1.346 1.611-.045V2.066c0-1.092-1.418-.025-1.418-.025L4.637 8.725zM20.006 6.709a1.18 1.18 0 0 0-1.668 0 1.176 1.176 0 0 0 0 1.666 7.734 7.734 0 0 1 2.273 5.484 7.752 7.752 0 0 1-2.273 5.495 1.184 1.184 0 0 0 0 1.672c.23.23.531.344.836.344.301 0 .602-.113.832-.344a10.107 10.107 0 0 0 2.963-7.167 10.075 10.075 0 0 0-2.963-7.15z"/>
        </symbol>
        <symbol id="icon-repeat" viewBox="0 0 1024 1024" width="100%" height="100%">
        	<path fill="var(--button-icon-fill-color)" class="path1" d="M874.022 149.98c-92.652-92.656-220.636-149.98-362.022-149.98-219.488 0-406.69 138.128-479.498 332.188l119.876 44.954c54.604-145.546 195.006-249.142 359.622-249.142 106.040 0 202.020 43 271.506 112.494l-143.506 143.506h384v-384l-149.978 149.98zM512 896c-106.040 0-202.026-42.992-271.512-112.488l143.512-143.512h-384v384l149.994-149.994c92.646 92.662 220.618 149.994 362.006 149.994 219.49 0 406.692-138.128 479.5-332.188l-119.876-44.954c-54.604 145.546-195.006 249.142-359.624 249.142z"></path>
        </symbol>
        <symbol id="icon-shuffle" viewBox="0 0 1024 1024" width="100%" height="100%">
        	<path fill="var(--button-icon-fill-color)" class="path1" d="M1024 256l-256-256v192c-130.772 0-230.752 31.208-305.65 95.408-5.25 4.5-10.284 9.1-15.162 13.774 27.52 38.164 48.716 77.516 67.772 115.090 48.322-58.402 118.054-96.272 253.040-96.272v384c-216.446 0-265.126-97.36-326.756-220.622-34.306-68.612-69.78-139.56-135.592-195.97-74.9-64.2-174.88-95.408-305.652-95.408v128c216.446 0 265.126 97.36 326.756 220.622 34.306 68.612 69.78 139.56 135.592 195.97 74.9 64.2 174.882 95.408 305.652 95.408v192l256-256-256-256 256-256zM0 704v128c130.772 0 230.75-31.208 305.65-95.408 5.25-4.498 10.284-9.1 15.162-13.776-27.52-38.162-48.718-77.516-67.772-115.090-48.32 58.402-118.052 96.274-253.040 96.274z"></path>
        </symbol>
      </svg>
    `;
  }
  static get controls() {
    return html`
      <div class="controls">
        <span class="playback">
          <button action="play" title="start playback"><svg class="icon"><use xlink:href="#icon-play" /></svg></button>
          <button action="pause" title="pause playback"><svg class="icon"><use xlink:href="#icon-pause" /></svg></button>
          <button action="stop" title="stop playback"><svg class="icon"><use xlink:href="#icon-stop" /></svg></button>
          <button action="prev" title="play previous track"><svg class="icon"><use xlink:href="#icon-previous" /></svg></button>
          <button action="next" title="play next track"><svg class="icon"><use xlink:href="#icon-next" /></svg></button>
        </span>
        <span class="playlist">
          <button action="shuffle" title="toggle shuffling"><svg class="icon"><use xlink:href="#icon-shuffle" /></svg></button>
          <button action="repeat" title="toggle repitition"><svg class="icon"><use xlink:href="#icon-repeat" /></svg></button>
        </span>
        <span class="volume">
          <button action="mute" title="mute playback"><svg class="icon"><use xlink:href="#icon-volume-mute" /></svg></button>
          <button action="volume-down" title="turn volume down"><svg class="icon"><use xlink:href="#icon-volume-down" /></svg></button>
          <button action="volume-up" title="turn volume up"><svg class="icon"><use xlink:href="#icon-volume-up" /></svg></button>
        </span>
      </div>
    `;
  }

  static get tracklist() {
    return html`
      <ul class="tracklist"></ul>
    `;
  }

  static get screen() {
    return html`
    <div class="info-box">
      <div class="track-info-box">
        <span class="track-title-text"></span>
        <span class="audio-time">
          <span class="current-time">00:00</span> /
          <span class="duration">00:00</span>
        </span>
      </div>
      ${this.progressbar}
    </div>
    `;

  }

  static get progressbar() {
    return html`
    <div class="progress-box">
      <div class="progress-cell">
        <div class="progress">
          <div class="progress-buffer"></div>
          <button class="progress-indicator"></button>
        </div>
      </div>
    </div>
    `;
  }

  static get template() {
    return html`
      <style>
      :host {
        --button-text-color: #fefefe;
        --button-icon-fill-color: #fefefe;
        --button-icon-fill-color-disabled: #dedede;
        --button-background-color: #094296;
        --button-background-color-hover: #1952A6;
        --button-background-color-active: #1952A6;
        --button-background-color-disabled: #4982D6;

        --playlist-border: 1px solid #094296;
        --playlist-background-color: #fefefe;
        --playlist-hover-color: #A9E2FF;
        --playlist-separator: none;

        --progress-bar-color: #094296;
        --progress-bar-border: 1px solid #d9d9d9;
        --progress-indicator-color: #fefefe;
        --progress-background-color: #fefefe;

        --panel-spacing: 0.5rem;

        display: block;
      }

      [aria-hidden="true"] {
        display: none !important;
      }

      .title {
        display: block;
        font-size: 1.125rem;
        text-align: left;
      }

      :host button {
        display: inline-block;
        vertical-align: middle;
        width: auto;
        height: auto;
        margin: 0;
        padding: 0.5rem 0.5rem 0.3rem 0.5rem;
        border: 1px solid transparent;
        border-radius: .125rem;
        transition: background-color 0.25s ease-out,color 0.25s ease-out;
        font-family: inherit;
        font-size: 0.75rem;
        -webkit-appearance: none;
        line-height: 1;
        text-align: center;
        cursor: pointer;
        background-color: var(--button-background-color);
        color: var(--button-text-color);
      }
      :host button:hover {
        --button-background-color: var(--button-background-color-hover);
      }
      :host button:active,
      :host button[activated] {
        --button-background-color: var(--button-background-color-active);
      }
      :host button:disabled {
        --button-background-color: var(--button-background-color-disabled);
        --button-icon-fill-color: var(--button-icon-fill-color-disabled);
        cursor: default;
      }

      .controls {
        margin-top: var(--panel-spacing);
      }
      .controls .icon {
        width: 1em;
        height: 1em;
      }

      .tracklist {
        margin-top: 0.5rem;
        list-style-type: none;
        padding: 0.25rem;
        border: var(--playlist-border);
        background-color: var(--playlist-background-color);
      }
      .tracklist:empty {
        display: none;
      }
      .tracklist .icon {
        width: .5rem;
        height: .5rem;
      }
      .tracklist .play-list-row {
        margin-bottom: 0.25rem;
        padding: 0.125rem;
        border-bottom: var(--playlist-separator);
      }
      .tracklist .play-list-row:last-child {
        border-bottom: none;
      }
      .tracklist .play-list-row:hover {
        background-color: var(--playlist-hover-color);
      }
      .tracklist button {
        position: relative;
        top: -1px;
        padding: 0em 0em;
        height: 1rem;
        width: 1rem;
        text-align: center;
      }
      .tracklist button .play {
        display: inline-block;
      }
      .tracklist button .stop {
        display: none;
      }
      .tracklist button[playing] .play {
        display: none;
      }
      .tracklist button[playing] .stop {
        display: inline-block;
      }
      .tracklist .track-number {
        text-align: right;
        width: 20px;
        display: inline-block;
      }

      .info-box {
        margin-top:  var(--panel-spacing);
      }
      .info-box:before, .info-box:after {
        content: " ";
        display: table;
      }
      .info-box:after {
        clear: both;
        display: block;
        font-size: 0;
        height: 0;
        visibility: hidden;
      }

      .progress-box {
        float: left;
        width: 100%;
        position: relative;
        margin-top:  var(--panel-spacing);
      }
      .progress-box .progress-cell {
        height: 12px;
        position: relative;
      }
      .progress-box .progress-cell .progress {
        background: var(--progress-background-color);
        border: var(--progress-bar-border);
        height: 8px;
        position: relative;
        width: auto;
      }
      .progress-box .progress-cell .progress .progress-buffer {
        background: var(--progress-bar-color);
        height: 100%;
        width: 0;
      }
      .progress-box .progress-cell .progress .progress-indicator {
        background: var(--progress-indicator-color);
        border: var(--progress-bar-border);
        border-radius: 3px;
        cursor: pointer;
        height: 12px;
        left: 0;
        padding: 0;
        overflow: hidden;
        position: absolute;
        top: -2px;
        width: 22px;
      }
      </style>
      ${this.svgIcons}
      <span class="title">[[title]]</span>
      <audio preload="none" tabindex="0"><slot></slot>Your browser does not support HTML5 audio.</audio>
      ${this.screen}
      ${this.controls}
      ${this.tracklist}
    `;

  }

  static get properties() {
    return {
      title: {
        type: String,
        value: 'audio-player',
        notify: true

      },
      play: {
        type: Boolean,
        value: true,
        notify: true

      },
      stop: {
        type: Boolean,
        value: true,
        notify: true

      },
      pause: {
        type: Boolean,
        value: false,
        notify: true

      },
      prev: {
        type: Boolean,
        value: false,
        notify: true

      },
      next: {
        type: Boolean,
        value: false,
        notify: true

      },
      repeat: {
        type: Boolean,
        value: false,
        notify: true

      },
      shuffle: {
        type: Boolean,
        value: false,
        notify: true

      },
      mute: {
        type: Boolean,
        value: false,
        notify: true

      },
      'volume-up': {
        type: Boolean,
        value: false,
        notify: true

      },
      'volume-down': {
        type: Boolean,
        value: false,
        notify: true

      },
      info: {
        type: Boolean,
        value: true,
        notify: true

      },
      progress: {
        type: Boolean,
        value: true,
        notify: true

      },
      time: {
        type: String,
        value: 'remain',
        notify: true

      },
      tracklist: {
        type: Boolean,
        value: false,
        notify: true

      }
    };
  }

  initDisplay() {
    // element attributes/properties
    let buttons = ['play', 'pause', 'stop', 'prev', 'next', 'repeat', 'shuffle', 'mute', 'volume-up', 'volume-down']
    let panels = ['info', 'progress', 'tracklist']

    buttons.forEach((button) => {
      let $button = this.shadowRoot.querySelector(`[action="${button}"]`)
      if (!$button) return
      if (!this.get(button) || this.get(button)=='false') {
        $button.setAttribute('aria-hidden', true)
      } else {
        $button.removeAttribute('aria-hidden')
      }
    })

    panels.forEach((panel) => {
      let $panel = this.shadowRoot.querySelector(`[class*="${panel}" i]`)
      if ($panel) {
        if (!this.get(panel) || this.get(panel)=='false') {
          $panel.setAttribute('aria-hidden', true)
        } else {
          $panel.removeAttribute('aria-hidden')
        }
      }
    })

  }

  tracklistItem( item ) {
    return `
    <li class="play-list-row" data-track-row="${item.index}">
      <button class="small-toggle-btn" title="toggle playback of track no. ${item.index}">
        <svg class="icon play"><use xlink:href="#icon-play" /></svg>
        <svg class="icon stop"><use xlink:href="#icon-pause" /></svg>
      </button>
      <span class="track-number">${item.index}.</span>
      <span class="track-title"><a class="playlist-track" href="#" data-play-track="${item.index}">${item.title}</a></span>
    </li>
    `;
  }

  initTracklist() {
    let sources = this.sources;
    let tracklist = this.shadowRoot.querySelector('.tracklist')
    sources.forEach((source, index) => {
      let item = { index: (index+1), title: source.getAttribute('title'), src: source.getAttribute('src') }
      let listItem = this.tracklistItem(item)
      tracklist.innerHTML += (listItem)
    })
    let slotted = this.shadowRoot.querySelector('slot').assignedNodes()
    let trackNumber = 1
    slotted.forEach((source) => {
      if (source instanceof HTMLSourceElement) source.dataset.trackNumber = (trackNumber++)
    })
  }

  initPropertyChangeEvents() {
    let props = [
      'play', 'pause', 'stop', 'prev', 'next', 'repeat', 'shuffle',
      'mute', 'volume-up', 'volume-down',
      'info', 'progress', 'tracklist'
    ]
    let $this = this
    props.forEach((prop) => {
      let eventName = `${prop}-changed`
      $this.addEventListener(eventName, (e) => {
        console.log('prop changed:', prop, e)
        $this.initDisplay.apply($this)
      }, false)
    })
  }

  get sources() {
    return this.querySelectorAll('source[src$=".mp3" i]')
  }
  get audioelement() {
    return this.shadowRoot.querySelector('audio')
  }

  get videoelement() {
    return this.shadowRoot.querySelector('video')
  }

  ready() {
    super.ready();
    // element's "on-ready"...

    this.initDisplay()
    this.initTracklist()
    this.initPropertyChangeEvents()

    this.audioPlayer = new audioPlayer(this)
    //this.audioPlayer = new audioPlayer({host: this.shadowRoot})
    this.audioPlayer.initPlayer()

  }

}


window.customElements.define('audio-player', AudioPlayer);
+0 −0

File added.

Preview size limit exceeded, changes collapsed.

+35 −0
Original line number Diff line number Diff line
<!DOCTYPE html><html lang="en"><head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1, user-scalable=yes">
    <title>audio-player demo</title>
    <script src="node_modules/@webcomponents/webcomponentsjs/webcomponents-loader.js"></script>
    <script type="module" src="audio-player.js"></script>
  </head>
  <body>
    <audio-player title="Party Rock Collection" prev="" next="" tracklist="">
      <source src="https://mp31.phononet.de/buchde/d2/009/415/LOEZPAGHXLYRCKBZWAGMOEPHRLCK.mp3" title="Party Rock Anthem">
      <source src="https://mp31.phononet.de/buchde/d2/009/415/LOEZPAGHXLYRCKBZWAGMOEPHRLAX.mp3" title="I Gotta Feeling (Edit)">
      <source src="https://mp31.phononet.de/buchde/d2/009/415/LOEZPAGHXLYRCKBZWAGMOEPHRLAC.mp3" title="When Love Takes Over">
      <source src="https://mp31.phononet.de/buchde/d2/009/415/LOEZPAGHXLYRCKBZWAGMOEPHRLXW.mp3" title="Don't Stop The Music (Album Version)">
      <source src="https://mp31.phononet.de/buchde/d2/009/415/LOEZPAGHXLYRCKBZWAGMOEPHRLXA.mp3" title="Heavy Cross (Album Version)">
      <source src="https://mp31.phononet.de/buchde/d2/009/415/LOEZPAGHXLYRCKBZWAGMOEPHRLXY.mp3" title="On The Floor (Radio Edit; No Rap)">
      <source src="https://mp31.phononet.de/buchde/d2/009/415/LOEZPAGHXLYRCKBZWAGMOEPHRXLA.mp3" title="Hangover">
      <source src="https://mp31.phononet.de/buchde/d2/009/415/LOEZPAGHXLYRCKBZWAGMOEPHRXLY.mp3" title="Poker Face">
      <source src="https://mp31.phononet.de/buchde/d2/009/415/LOEZPAGHXLYRCKBZWAGMOEPHRXLC.mp3" title="Moves Like Jagger (Studio Recording From The Voice Performance)">
      <source src="https://mp31.phononet.de/buchde/d2/009/415/LOEZPAGHXLYRCKBZWAGMOEPHRXYW.mp3" title="Ding (Single Version)">
      <source src="https://mp31.phononet.de/buchde/d2/009/415/LOEZPAGHXLYRCKBZWAGMOEPHRXYL.mp3" title="Alles neu (Single Version)">
      <source src="https://mp31.phononet.de/buchde/d2/009/415/LOEZPAGHXLYRCKBZWAGMOEPHRXWO.mp3" title="Hamma! (Single Edit)">
      <source src="https://mp31.phononet.de/buchde/d2/009/415/LOEZPAGHXLYRCKBZWAGMOEPHRXWL.mp3" title="Türlich, Türlich (sicher, Dicker) (Album Version)">
      <source src="https://mp31.phononet.de/buchde/d2/009/415/LOEZPAGHXLYRCKBZWAGMOEPHRXWY.mp3" title="Don't Cha (Main Mix)">
      <source src="https://mp31.phononet.de/buchde/d2/009/415/LOEZPAGHXLYRCKBZWAGMOEPHRXWC.mp3" title="TiK ToK">
      <source src="https://mp31.phononet.de/buchde/d2/009/415/LOEZPAGHXLYRCKBZWAGMOEPHRXLW.mp3" title="Get Busy">
      <source src="https://mp31.phononet.de/buchde/d2/009/415/LOEZPAGHXLYRCKBZWAGMOEPHRXCK.mp3" title="Alors on danse (Radio Edit)">
      <source src="https://mp31.phononet.de/buchde/d2/009/415/LOEZPAGHXLYRCKBZWAGMOEPHRCWO.mp3" title="Horny '98">
      <source src="https://mp31.phononet.de/buchde/d2/009/415/LOEZPAGHXLYRCKBZWAGMOEPHRCWL.mp3" title="Remmidemmi (Yippie Yippie Yeah) (Single Edit)">
      <source src="https://mp31.phononet.de/buchde/d2/009/415/LOEZPAGHXLYRCKBZWAGMOEPHRCWX.mp3" title="Played-A-Live (The Bongo Song) (Radio Cut)">
      <source src="https://mp31.phononet.de/buchde/d2/009/415/LOEZPAGHXLYRCKBZWAGMOEPHRCWK.mp3" title="Gangnam Style (     )">
    </audio-player>
  

</body></html>
 No newline at end of file