initial commit
29
COPYING.txt
Normal file
@ -0,0 +1,29 @@
|
||||
This software includes sources and binaries from:
|
||||
|
||||
jQuery
|
||||
Copyright 2014 jQuery Foundation and other contributors
|
||||
http://jquery.com/
|
||||
|
||||
MediaElement.js
|
||||
Copyright 2010-2013, John Dyer (http://j.hn)
|
||||
http://mediaelementjs.com/
|
||||
|
||||
MediaElement Playlist Feature (plugin) -
|
||||
Andrew Berezovsky <andrew.berezovsky@gmail.com>
|
||||
and Junaid Qadir Baloch <shekhanzai.baloch@gmail.com>
|
||||
https://github.com/duozersk/mep-feature-playlist
|
||||
|
||||
JavaScript-ID3-Reader
|
||||
Copyright (c) 2008 Jacob Seidelin, http://blog.nihilogic.dk/ BSD License
|
||||
Copyright (c) 2009 Opera Software ASA BSD License
|
||||
Copyright (c) 2010 AntÃâ³nio Afonso BSD License
|
||||
Copyright (c) 2010 Joshua Kifer BSD License
|
||||
https://github.com/aadsm/JavaScript-ID3-Reader
|
||||
|
||||
This software is:
|
||||
|
||||
MyPlayer
|
||||
Copyright 2014 tilt@linuxfoo.de MIT License
|
||||
|
||||
See the file LICENSE.txt for licensing information
|
||||
or contact the author for additional information.
|
20
LICENSE.txt
Normal file
@ -0,0 +1,20 @@
|
||||
MyPlayer
|
||||
Copyright (C) 2014 tilt@linuxfoo.de
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
32
README.txt
Normal file
@ -0,0 +1,32 @@
|
||||
Project: MyPlayer - A Web-MP3-Player with Playlist Support
|
||||
Author: tilt@linuxfoo.de
|
||||
Release: 01-10-2014
|
||||
License: MIT
|
||||
|
||||
About:
|
||||
|
||||
This project provides a JavaScript constructor MyPlayer({...options...}) that can be used
|
||||
to embed lists of audio files as read from an index document or an M3U into a web document.
|
||||
|
||||
They will be displayed in a playback GUI with a playlist that can optionally be filled
|
||||
from the "title" and "artist" values of the files' ID3 tags (v1 and v2 are supported).
|
||||
|
||||
The player is "detachable", meaning it can start in a detached state or the user can open
|
||||
it in a new window, preventing that playback breaks when the user leaves the page.
|
||||
|
||||
Tested Compatibility:
|
||||
|
||||
MP3: Firefox, Chrome, Internet Exploder
|
||||
OGG Audio: Firefox, Chrome
|
||||
|
||||
How to Use:
|
||||
|
||||
See demos/index.html for several examples.
|
||||
|
||||
How to Hack:
|
||||
|
||||
Directory src contains the input files. See player.js for the MyPLayer implementation.
|
||||
Use build.sh (with the Google closure compiler) to rebuild myplayer.min.js.
|
||||
|
||||
The Flash and Silverlight plugins are taken from mediaelement.js and are included
|
||||
in binary form only. If you want to modify them, use the mediaelement.js sources.
|
2
RELEASE.txt
Normal file
@ -0,0 +1,2 @@
|
||||
2-10-2014: fixed a bug in EXTINF parsing (time=-1).
|
||||
1-10-2014: initial release.
|
BIN
css/ajax-loader.gif
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
css/background.png
Normal file
After Width: | Height: | Size: 166 B |
BIN
css/bigplay.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
1
css/bigplay.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?>
<!-- Generator: Adobe Fireworks CS6, Export SVG Extension by Aaron Beall (http://fireworks.abeall.com) . Version: 0.6.1 -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg id="bigplay-gradient.fw-Page%201" viewBox="0 0 100 200" style="background-color:#ffffff00" version="1.1"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve"
x="0px" y="0px" width="100px" height="200px"
>
<defs>
<radialGradient id="gradient1" cx="50%" cy="50%" r="50%">
<stop stop-color="#222222" stop-opacity="0" offset="70%"/>
<stop stop-color="#222222" stop-opacity="0.0118" offset="70.202%"/>
<stop stop-color="#333333" stop-opacity="1" offset="85%"/>
<stop stop-color="#333333" stop-opacity="0" offset="100%"/>
</radialGradient>
<radialGradient id="gradient2" cx="50%" cy="50%" r="50%">
<stop stop-color="#bbbbbb" stop-opacity="0" offset="70%"/>
<stop stop-color="#bbbbbb" stop-opacity="0.0118" offset="70.202%"/>
<stop stop-color="#bbbbbb" stop-opacity="1" offset="85%"/>
<stop stop-color="#bbbbbb" stop-opacity="0" offset="100%"/>
</radialGradient>
<filter id="filter1" x="-100%" y="-100%" width="300%" height="300%">
<!-- Glow -->
<feColorMatrix result="out" in="SourceGraphic" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.251 0"/>
<feMorphology result="out" in="out" operator="dilate" radius="3"/>
<feGaussianBlur result="out" in="out" stdDeviation="1.5"/>
<feBlend in="SourceGraphic" in2="out" mode="normal" result="Glow1"/>
</filter>
<filter id="filter2" x="-100%" y="-100%" width="300%" height="300%">
<!-- Glow -->
<feColorMatrix result="out" in="SourceGraphic" type="matrix" values="0 0 0 0.8667 0 0 0 0 0.8667 0 0 0 0 0.8667 0 0 0 0 0.251 0"/>
<feMorphology result="out" in="out" operator="dilate" radius="3"/>
<feGaussianBlur result="out" in="out" stdDeviation="1.5"/>
<feBlend in="SourceGraphic" in2="out" mode="normal" result="Glow2"/>
</filter>
</defs>
<g id="Background">
</g>
<g id="dark%20shadow">
<path d="M 22 50 C 22 34.5358 34.5358 22 50 22 C 65.4642 22 78 34.5358 78 50 C 78 65.4642 65.4642 78 50 78 C 34.5358 78 22 65.4642 22 50 ZM 5 50 C 5 74.8531 25.1469 95 50 95 C 74.8531 95 95 74.8531 95 50 C 95 25.1469 74.8531 5 50 5 C 25.1469 5 5 25.1469 5 50 Z" fill="url(#gradient1)"/>
<path d="M 22 150 C 22 134.5358 34.5358 122 50 122 C 65.4642 122 78 134.5358 78 150 C 78 165.4642 65.4642 178 50 178 C 34.5358 178 22 165.4642 22 150 ZM 5 150 C 5 174.8531 25.1469 195 50 195 C 74.8531 195 95 174.8531 95 150 C 95 125.1469 74.8531 105 50 105 C 25.1469 105 5 125.1469 5 150 Z" fill="url(#gradient2)"/>
</g>
<g id="dark">
<path id="Polygon" filter="url(#filter1)" d="M 72.5 49.5 L 38.75 68.9856 L 38.75 30.0144 L 72.5 49.5 Z" fill="#ffffff"/>
<path id="Ellipse" d="M 13 50.5 C 13 29.7891 29.7891 13 50.5 13 C 71.2109 13 88 29.7891 88 50.5 C 88 71.2109 71.2109 88 50.5 88 C 29.7891 88 13 71.2109 13 50.5 Z" stroke="#ffffff" stroke-width="5" fill="none"/>
</g>
<g id="light">
<path id="Polygon2" filter="url(#filter2)" d="M 72.5 149.5 L 38.75 168.9856 L 38.75 130.0144 L 72.5 149.5 Z" fill="#ffffff"/>
<path id="Ellipse2" d="M 13 150.5 C 13 129.7891 29.7891 113 50.5 113 C 71.2109 113 88 129.7891 88 150.5 C 88 171.211 71.2109 188 50.5 188 C 29.7891 188 13 171.211 13 150.5 Z" stroke="#ffffff" stroke-width="5" fill="none"/>
</g>
</svg>
|
After Width: | Height: | Size: 3.4 KiB |
BIN
css/controls-playlist.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
css/controls.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
1
css/controls.svg
Normal file
After Width: | Height: | Size: 10 KiB |
0
css/custom.css
Normal file
4
css/index.css
Normal file
@ -0,0 +1,4 @@
|
||||
div.home { font-size: 1em; }
|
||||
div.home a { display: inline-block; margin: 0 .2em 0 .2em; text-decoration: none; }
|
||||
h1 { margin-top: 0; }
|
||||
|
69
css/local.css
Normal file
@ -0,0 +1,69 @@
|
||||
html {
|
||||
overflow: hidden;
|
||||
height: 100%
|
||||
}
|
||||
body {
|
||||
background: black;
|
||||
}
|
||||
.mejs-audio {
|
||||
}
|
||||
.mejs-controls {
|
||||
top: 0!important;
|
||||
padding: 3px 0 0 0;
|
||||
height: 2em!important;
|
||||
background: none!important;
|
||||
border-top: 2em!important;
|
||||
}
|
||||
.mejs-controls .mejs-time-rail .mejs-time-loaded {
|
||||
background: #5a1a7a!important;
|
||||
}
|
||||
.mejs-controls .mejs-time-rail .mejs-time-float {
|
||||
top: 2.5em!important;
|
||||
}
|
||||
.mejs-controls .mejs-time-rail .mejs-time-float .mejs-time-float-corner {
|
||||
display: none!important;
|
||||
}
|
||||
.mejs li {
|
||||
font-size: 0.8em!important;
|
||||
line-height: 1em!important;
|
||||
color: #ccddff;
|
||||
}
|
||||
.mejs-playlist {
|
||||
width: 430px!important;
|
||||
height: 265px!important;
|
||||
}
|
||||
.popupButton {
|
||||
display: inline-block!important;
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
}
|
||||
.popupButton button {
|
||||
overflow: hidden;
|
||||
width: 25px;
|
||||
height: 22px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
background: url(popup.png);
|
||||
cursor: pointer;
|
||||
}
|
||||
.playerDetached {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
font-size: small;
|
||||
font-family: sans-serif;
|
||||
color: #cacaca;
|
||||
}
|
||||
.ajaxLoader {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
display: inline-block;
|
||||
background: url(ajax-loader.gif);
|
||||
}
|
||||
noscript {
|
||||
color: white;
|
||||
font-family: sans-serif;
|
||||
}
|
1001
css/mediaelementplayer.css
Normal file
68
css/mep-feature-playlist.css
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
Document : mep-feature-playlist.css
|
||||
Author : Andrew Berezovsky <andrew.berezovsky@gmail.com>
|
||||
Original Author : Junaid Qadir Baloch <shekhanzai.baloch@gmail.com>
|
||||
*/
|
||||
|
||||
/* Start: Show/Hide Playlist*/
|
||||
.mejs-controls .mejs-show-playlist button {
|
||||
background: transparent url(controls-playlist.png) no-repeat;
|
||||
background-position: -16px -16px;
|
||||
}
|
||||
.mejs-controls .mejs-hide-playlist button {
|
||||
background: transparent url(controls-playlist.png) no-repeat;
|
||||
background-position: -16px 0;
|
||||
}
|
||||
/* End: Show/Hide Playlist */
|
||||
|
||||
/* Start: Previous */
|
||||
.mejs-controls .mejs-prevtrack button {
|
||||
background: transparent url(controls-playlist.png) no-repeat;
|
||||
background-position: 0 -16px;
|
||||
}
|
||||
/* End: Previous */
|
||||
|
||||
/* Start: Next */
|
||||
.mejs-controls .mejs-nexttrack button {
|
||||
background: transparent url(controls-playlist.png) no-repeat;
|
||||
}
|
||||
/* End: Next */
|
||||
|
||||
/* Start: Shuffle */
|
||||
.mejs-controls .mejs-shuffle-on button {
|
||||
background: transparent url(controls-playlist.png) no-repeat;
|
||||
background-position: -32px 0;
|
||||
}
|
||||
.mejs-controls .mejs-shuffle-off button {
|
||||
background: transparent url(controls-playlist.png) no-repeat;
|
||||
background-position: -32px -16px;
|
||||
}
|
||||
/* End: Shuffle */
|
||||
|
||||
/*Start: Playlist*/
|
||||
.mejs-playlist {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
height: 200px!important;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.mejs-playlist ul {
|
||||
margin: 0;
|
||||
padding: 5px;
|
||||
}
|
||||
.mejs-playlist li {
|
||||
color: white;
|
||||
font-size: 11px;
|
||||
height: 16px;
|
||||
overflow: hidden;
|
||||
margin: 2px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.mejs-playlist li:hover {
|
||||
color: #a8a8a8;
|
||||
}
|
||||
.mejs-playlist li.current {
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
}
|
||||
/*End: Playlist*/
|
3
css/myplayer.css
Normal file
@ -0,0 +1,3 @@
|
||||
@import url('mediaelementplayer.css');
|
||||
@import url('mep-feature-playlist.css');
|
||||
@import url('local.css');
|
BIN
css/popup.png
Normal file
After Width: | Height: | Size: 744 B |
26
demo/autoplay.html
Normal file
@ -0,0 +1,26 @@
|
||||
<html>
|
||||
<head>
|
||||
<base href="." />
|
||||
|
||||
<title>MyPlayer Autoplay/Loop Demo</title>
|
||||
|
||||
<script type="text/javascript" src="../js/jquery.js"></script>
|
||||
<script type="text/javascript" src="../js/myplayer.min.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="../css/myplayer.css" />
|
||||
|
||||
<script type="text/javascript">$(function(){MyPlayer({
|
||||
mode: 'm3u',
|
||||
m3u: './snd/play.m3u',
|
||||
id3: true,
|
||||
autoplay: true,
|
||||
loop: false
|
||||
})});</script>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
Javascript is required to use the MP3 player.
|
||||
Please choose of the alternatives listed below.
|
||||
</noscript>
|
||||
</body>
|
||||
</html>
|
28
demo/detachable.html
Normal file
@ -0,0 +1,28 @@
|
||||
<html>
|
||||
<head>
|
||||
<base href="." />
|
||||
|
||||
<title>MyPlayer Detachable Demo</title>
|
||||
|
||||
<script type="text/javascript" src="../js/jquery.js"></script>
|
||||
<script type="text/javascript" src="../js/myplayer.min.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="../css/myplayer.css" />
|
||||
|
||||
<script type="text/javascript">$(function(){MyPlayer({
|
||||
mode: 'm3u',
|
||||
m3u: './snd/play.m3u',
|
||||
detachable: false
|
||||
})});</script>
|
||||
|
||||
<style type="text/css">
|
||||
h1, p { color: white; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
Javascript is required to use the MP3 player.
|
||||
Please choose of the alternatives listed below.
|
||||
</noscript>
|
||||
</body>
|
||||
</html>
|
34
demo/element.html
Normal file
@ -0,0 +1,34 @@
|
||||
<html>
|
||||
<head>
|
||||
<base href="." />
|
||||
|
||||
<title>MyPlayer Element Demo</title>
|
||||
|
||||
<script type="text/javascript" src="../js/jquery.js"></script>
|
||||
<script type="text/javascript" src="../js/myplayer.min.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="../css/myplayer.css" />
|
||||
|
||||
<script type="text/javascript">$(function(){MyPlayer({
|
||||
element: '#myplayer',
|
||||
mode: 'm3u',
|
||||
m3u: './snd/play.m3u'
|
||||
})});</script>
|
||||
|
||||
<style type="text/css">
|
||||
h1, p { color: white; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
Javascript is required to use the MP3 player.
|
||||
Please choose of the alternatives listed below.
|
||||
</noscript>
|
||||
|
||||
<h1>I Am A Heading</h1>
|
||||
|
||||
<p>I am a paragraph. The player UI will follow below.</p>
|
||||
|
||||
<div id="myplayer"></div>
|
||||
</body>
|
||||
</html>
|
23
demo/extm3u.html
Normal file
@ -0,0 +1,23 @@
|
||||
<html>
|
||||
<head>
|
||||
<base href="." />
|
||||
|
||||
<title>MyPlayer EXTM3U Demo</title>
|
||||
|
||||
<script type="text/javascript" src="../js/jquery.js"></script>
|
||||
<script type="text/javascript" src="../js/myplayer.min.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="../css/myplayer.css" />
|
||||
|
||||
<script type="text/javascript">$(function(){MyPlayer({
|
||||
mode: 'm3u',
|
||||
m3u: './snd/play.extm3u'
|
||||
})});</script>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
Javascript is required to use the MP3 player.
|
||||
Please choose of the alternatives listed below.
|
||||
</noscript>
|
||||
</body>
|
||||
</html>
|
24
demo/filematch.html
Normal file
@ -0,0 +1,24 @@
|
||||
<html>
|
||||
<head>
|
||||
<base href="." />
|
||||
|
||||
<title>MyPlayer filematch Demo</title>
|
||||
|
||||
<script type="text/javascript" src="../js/jquery.js"></script>
|
||||
<script type="text/javascript" src="../js/myplayer.min.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="../css/myplayer.css" />
|
||||
|
||||
<script type="text/javascript">$(function(){MyPlayer({
|
||||
mode: 'm3u',
|
||||
m3u: './snd/play.m3u',
|
||||
filematch: /(^|\/)[0-9][^\/]*\.mp3/i
|
||||
})});</script>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
Javascript is required to use the MP3 player.
|
||||
Please choose of the alternatives listed below.
|
||||
</noscript>
|
||||
</body>
|
||||
</html>
|
24
demo/id3.html
Normal file
@ -0,0 +1,24 @@
|
||||
<html>
|
||||
<head>
|
||||
<base href="." />
|
||||
|
||||
<title>MyPlayer ID3 Demo</title>
|
||||
|
||||
<script type="text/javascript" src="../js/jquery.js"></script>
|
||||
<script type="text/javascript" src="../js/myplayer.min.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="../css/myplayer.css" />
|
||||
|
||||
<script type="text/javascript">$(function(){MyPlayer({
|
||||
mode: 'm3u',
|
||||
m3u: './snd/play.m3u',
|
||||
id3: true
|
||||
})});</script>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
Javascript is required to use the MP3 player.
|
||||
Please choose of the alternatives listed below.
|
||||
</noscript>
|
||||
</body>
|
||||
</html>
|
255
demo/index.html
Normal file
@ -0,0 +1,255 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>MyPlayer Demos</title>
|
||||
</head>
|
||||
<body>
|
||||
<a name="top"></a>
|
||||
|
||||
<p>[<a title="Back to Index" target="_self" href="../index.html">Back to Index</a>]</p>
|
||||
|
||||
<h1>MyPlayer Usage by Examples</h1>
|
||||
|
||||
<h2>Table of Contents</h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="#always" title="Alwas Required" target="_self">Always Required</a> - Including MyPlayer. Setting up MIME-Types.</li>
|
||||
<li><a href="#list" title="Mode "list"" target="_self">Mode "list"</a> - Playing a JavaScript array of audio file URLs and titles.</li>
|
||||
<li><a href="#mp3url" title="Mode "mp3url"" target="_self">Mode "mp3url"</a> - Reading lists of audio files from index documents.</li>
|
||||
<li><a href="#m3u" title="Mode "m3u"" target="_self">Mode "m3u"</a> - Reading lists of audio files from <tt>.m3u</tt> files.</li>
|
||||
<li><a href="#element" title="Option "element"" target="_self">Option "element"</a> - Where the player/playlist should be placed.</li>
|
||||
<li><a href="#detachable" title="Option "detachable"" target="_self">Option "detachable"</a> - If the player can be detached or not.</li>
|
||||
<li><a href="#id3" title="Option "id3"" target="_self">Option "id3"</a> - Interpreting ID3-tags.</li>
|
||||
<li><a href="#autoplay" title="Option "autoplay/loop/shuffle"" target="_self">Options "autoplay", "loop" and "shuffle"</a> - Player behavior and defaults.</li>
|
||||
<li><a href="#types" title="Option "types"" target="_self">Option "types"</a> - Specifying filename-endings to consider.</li>
|
||||
<li><a href="#filematch" title="Option "filematch"" target="_self">Option "filematch"</a> - Specifying an URL-matching expression.</li>
|
||||
<li><a href="#network" title="Option "network"" target="_self">Option "network"</a> - Limited support for network streams.</li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="always">Always Required</a></h2>
|
||||
|
||||
<p>To embed MyPlayer in your webpage put this in the <tt><head></tt>
|
||||
section of your document:
|
||||
|
||||
<pre><script type="text/javascript" src="/path/to/js/jquery.js"></script>
|
||||
<script type="text/javascript" src="/path/to/js/myplayer.min.js"></script>
|
||||
<link rel="stylesheet" href="/path/to/css/myplayer.css" /></pre>
|
||||
|
||||
<p>Some (most?) webservers should be configured to serve audio files with their correct
|
||||
MIME-Types so that playback in the browser works reliably. The following example
|
||||
for the Apache webserver could be included in a file <tt>.htaccess</tt> in the
|
||||
directory holding the audio files:</p>
|
||||
|
||||
<pre>AddType audio/mpeg .mp3
|
||||
AddType audio/ogg .ogg</pre>
|
||||
|
||||
<p>This example will enable correct MIME-Types when serving files that end with
|
||||
<tt>.mp3</tt> or <tt>.ogg</tt>.</p>
|
||||
|
||||
<h2><a name="list">Mode "list"</a></h2>
|
||||
|
||||
<p>If you have URLs of audio files as a JavaScript array, create the player
|
||||
with option <tt>mode</tt> set to <tt>"list"</tt>. The list items are passed
|
||||
either in object notation or as a plain strings containing the URLs:</p>
|
||||
|
||||
<pre><script type="text/javascript">$(function(){MyPlayer({
|
||||
mode: 'list',
|
||||
list: [
|
||||
{url: '/something.mp3', title: 'Something'},
|
||||
{url: 'http://example.com/snd/else.mp3'},
|
||||
"./entirely.ogg"
|
||||
]
|
||||
})});</script></pre>
|
||||
|
||||
<p>Demo: <a title="MyPlayer list Demo" href="list.html" target="_blank">list.html</a></p>
|
||||
|
||||
<p><i>Note:</i> The property <tt>title</tt> is optional, and if it is
|
||||
omitted, the last component of the URL path is used as a title in
|
||||
the playlist. In above example, the second entry's title would be
|
||||
<tt>else.mp3</tt> and the third one's would be <tt>entirely.ogg</tt>.</p>
|
||||
|
||||
<h2><a name="mp3url">Mode "mp3url"</a></h2>
|
||||
|
||||
<p>Play all links ending with <tt>.mp3</tt> found at a given URL <tt>mp3url</tt>:.
|
||||
|
||||
<pre><script type="text/javascript">$(function(){MyPlayer({
|
||||
mode: 'mp3url',
|
||||
mp3url: '/directory/with/your/mp3s/'
|
||||
})});</script></pre>
|
||||
|
||||
<p><i>Note:</i> Directory indexes should be enabled on the directory containing
|
||||
the files, when using the Apache webserver this can be possible by placing an
|
||||
<tt>.htaccess</tt> file into that directory:</p>
|
||||
|
||||
<pre>Options +Indexes</pre>
|
||||
|
||||
<p>Demo: <a title="MyPlayer mp3url Demo" href="mp3url.html" target="_blank">mp3url.html</a></p>
|
||||
|
||||
<h2><a name="m3u">Mode "m3u"</a></h2>
|
||||
|
||||
<p>Play all links found in an M3U-File specified by URL <tt>m3u</tt>:</p>
|
||||
|
||||
<pre><script type="text/javascript">$(function(){MyPlayer({
|
||||
mode: 'm3u',
|
||||
m3u: '/some/place/play.m3u'
|
||||
})});</script></pre>
|
||||
|
||||
<p>Demo: <a title="MyPlayer m3u Demo" href="m3u.html" target="_blank">m3u.html</a></p>
|
||||
|
||||
<p>If the M3U is in EXTM3U format, the player will attempt to parse the EXTINF
|
||||
information (playtime, title) where available.</p>
|
||||
|
||||
<p>Demo: <a title="MyPlayer extm3u Demo" href="extm3u.html" target="_blank">extm3u.html</a></p>
|
||||
|
||||
<p><i>Note:</i> The player will to some degree try to resolve relative entries
|
||||
in an M3U. If an entry is encountered that is not an absolute <tt>https?|ftp|file</tt>
|
||||
URL, it will try to make the entry absolute by prepending it with the path
|
||||
of the M3U.</p>
|
||||
|
||||
<p>Demo: <a title="MyPlayer relative m3u Demo" href="relative-m3u.html" target="_blank">relative-m3u.html</a></p>
|
||||
|
||||
<h2><a name="element">Option "element"</a></h2>
|
||||
|
||||
<p>The default for the player is to append its UI to the <tt><body></tt>
|
||||
of the current document. Using the <tt>element</tt> option you have more
|
||||
control over the placement of the player UI. This option uses jQuery selector
|
||||
notation.</p>
|
||||
|
||||
<p>Append the player UI to the contents of the element with ID <tt>myplayer</tt>:</p>
|
||||
|
||||
<pre><script type="text/javascript">$(function(){MyPlayer({
|
||||
element: '#myplayer',
|
||||
mode: 'm3u',
|
||||
m3u: '/some/place/play.m3u'
|
||||
})});</script></pre>
|
||||
|
||||
<p>Demo: <a title="MyPlayer element Demo" href="element.html" target="_blank">element.html</a></p>
|
||||
|
||||
<h2><a name="detachable">Option "detachable"</a></h2>
|
||||
|
||||
<p>The default for the player is to offer a "detach" button that will cause
|
||||
it to re-open itself in a separate (popup) window. If you do not
|
||||
want this, set the option <tt>detachable</tt> to <tt>false</tt>:</p>
|
||||
|
||||
<pre><script type="text/javascript">$(function(){MyPlayer({
|
||||
mode: 'm3u',
|
||||
m3u: '/some/place/play.m3u',
|
||||
detachable: false
|
||||
})});</script></pre>
|
||||
|
||||
<p>Demo: <a title="MyPlayer detachable Demo" href="detachable.html" target="_blank">detachable.html</a></p>
|
||||
|
||||
<h2><a name="id3">Option "id3"</a></h2>
|
||||
|
||||
<p><i>Important Note:</i> My tests prove the ID3 implementation provided
|
||||
here to be unreliable. Please use this option with caution. If you want
|
||||
to provide neatly formatted metadata for your tracks, please also consider
|
||||
the <tt><a href="#m3u">m3u</a></tt> option with EXTINF information.</p>
|
||||
|
||||
<p>Setting the option <tt>id3</tt> to <tt>true</tt> will cause the player
|
||||
to attempt reading artist name and track title from the ID3 tags found in
|
||||
the <tt>.mp3</tt> files.</p>
|
||||
|
||||
<p>Playback can commence before the lookups are complete (they might take
|
||||
a while). An Ajax loading indicator is displayed for a few seconds next to
|
||||
the tracks currently being looked up.</p>
|
||||
|
||||
<pre><script type="text/javascript">$(function(){MyPlayer({
|
||||
mode: 'm3u',
|
||||
m3u: '/some/place/play.m3u',
|
||||
id3: true
|
||||
})});</script></pre>
|
||||
|
||||
<p>Demo: <a title="MyPlayer id3 Demo" href="id3.html" target="_blank">id3.html</a></p>
|
||||
|
||||
<p><i>Note:</i> If you do not want the animated loading indicator, you
|
||||
can prevent it by setting the option <tt>loader</tt> to <tt>false</tt>.</p>
|
||||
|
||||
<h2><a name="autoplay">Options "autoplay", "loop", "shuffle"</a></h2>
|
||||
|
||||
<p>Setting the option <tt>autoplay</tt> to <tt>true</tt> will cause the
|
||||
player to immediately start playback when the site is ready.</p>
|
||||
|
||||
<p>Setting the option <tt>loop</tt> to <tt>false</tt> will cause the
|
||||
"Loop" function to be disabled when the player is loaded.</p>
|
||||
|
||||
<p>Setting the option <tt>shuffle</tt> to <tt>true</tt> will cause the
|
||||
"Shuffle" function to be enabled when the player is loaded.</p>
|
||||
|
||||
<pre><script type="text/javascript">$(function(){MyPlayer({
|
||||
mode: 'm3u',
|
||||
m3u: '/some/place/play.m3u',
|
||||
autoplay: true,
|
||||
loop: false,
|
||||
shuffle: true
|
||||
})});</script></pre>
|
||||
|
||||
<p>Demo: <a title="MyPlayer autoplay/loop/shuffle Demo" href="autoplay.html" target="_blank">autoplay.html</a></p>
|
||||
|
||||
<h2><a name="types">Option "types"</a></h2>
|
||||
|
||||
<p>Setting the option <tt>types</tt> to a non-empty array of strings
|
||||
will interpret those strings as filename endings to consider for playback.
|
||||
The matching will be performed case-insensitive.</p>
|
||||
|
||||
<p>The following example will build the playlist from the lines in
|
||||
the given <tt>play.m3u</tt>, but it will only consider entries that end
|
||||
with <tt>.ogg</tt>:</p>
|
||||
|
||||
<pre><script type="text/javascript">$(function(){MyPlayer({
|
||||
mode: 'm3u',
|
||||
m3u: '/some/place/play.m3u',
|
||||
types: ['ogg']
|
||||
})});</script></pre>
|
||||
|
||||
<p>Demo: <a title="MyPlayer types Demo" href="types.html" target="_blank">types.html</a></p>
|
||||
|
||||
<h2><a name="filematch">Option "filematch"</a></h2>
|
||||
|
||||
<p>Setting the option <tt>filematch</tt> to a RegExp object will cause
|
||||
filename matching to be performed using that regular expression.</p>
|
||||
|
||||
<p><i>Note:</i> If this option and the option <tt>types</tt> are both
|
||||
present, then this option has no effect, and the values in the array
|
||||
<tt>types</tt> apply instead.</p>
|
||||
|
||||
<p>The following example will build the playlist from the lines in
|
||||
the given <tt>play.m3u</tt>, but it will only consider entries that
|
||||
start with a digit and end with <tt>.ogg</tt>. Please note that
|
||||
matching is performed on the entire URL, so in order to match
|
||||
the filename only, more complex regular expressing is neccessary:</p>
|
||||
|
||||
<pre><script type="text/javascript">$(function(){MyPlayer({
|
||||
mode: 'm3u',
|
||||
m3u: '/some/place/play.m3u',
|
||||
filematch: /(^|\/)[0-9][^\/]*\.mp3/i
|
||||
})});</script></pre>
|
||||
|
||||
<p>Demo: <a title="MyPlayer filematch Demo" href="filematch.html" target="_blank">filematch.html</a></p>
|
||||
|
||||
<h2><a name="network">Option "network"</a></h2>
|
||||
|
||||
<p>Setting the option <tt>network</tt> to <tt>true</tt> enables limited support
|
||||
for network streams (native playback does not work with some broadcast servers).</p>
|
||||
|
||||
<p>All filename matching will be disabled, meaning the <tt>types</tt>
|
||||
and <tt>filematch</tt> options have no effect.</p>
|
||||
|
||||
<p>The timerail will be disabled in the GUI.</p>
|
||||
|
||||
<p>Play an M3U containing only network stream entries:</p>
|
||||
|
||||
<pre><script type="text/javascript">$(function(){MyPlayer({
|
||||
mode: 'm3u',
|
||||
m3u: 'http://example.com/streaming.m3u',
|
||||
network: true
|
||||
})});</script></pre>
|
||||
|
||||
<p>Demo: <a title="MyPlayer network Demo" href="network.html" target="_blank">network.html</a></p>
|
||||
|
||||
<p><i>Implementation Note:</i> if <tt>network</tt> is set to <tt>true</tt> then
|
||||
<tt>mediaelement.js</tt> will be forced to mode <tt>'native'</tt> on network streams
|
||||
(this is accomplished by a patch to <tt>mediaelement.js</tt>).</p>
|
||||
|
||||
<p>[<a title="Back to Top" target="_self" href="#top">Back to Top</a>]</p>
|
||||
</body>
|
||||
</html>
|
29
demo/list.html
Normal file
@ -0,0 +1,29 @@
|
||||
<html>
|
||||
<head>
|
||||
<base href="." />
|
||||
|
||||
<title>MyPlayer M3U Demo</title>
|
||||
|
||||
<script type="text/javascript" src="../js/jquery.js"></script>
|
||||
<script type="text/javascript" src="../js/myplayer.min.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="../css/myplayer.css" />
|
||||
|
||||
<script type="text/javascript">$(function(){MyPlayer({
|
||||
mode: 'list',
|
||||
list: [
|
||||
{ url: './snd/dreamz.mp3',
|
||||
title: 'tilt - Dreamz' },
|
||||
{ url: './snd/dreamz.mp3',
|
||||
title: 'tilt - Dreamz (#2)' },
|
||||
'./snd/dreamz.mp3',
|
||||
]
|
||||
})});</script>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
Javascript is required to use the MP3 player.
|
||||
Please choose of the alternatives listed below.
|
||||
</noscript>
|
||||
</body>
|
||||
</html>
|
23
demo/m3u.html
Normal file
@ -0,0 +1,23 @@
|
||||
<html>
|
||||
<head>
|
||||
<base href="." />
|
||||
|
||||
<title>MyPlayer M3U Demo</title>
|
||||
|
||||
<script type="text/javascript" src="../js/jquery.js"></script>
|
||||
<script type="text/javascript" src="../js/myplayer.min.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="../css/myplayer.css" />
|
||||
|
||||
<script type="text/javascript">$(function(){MyPlayer({
|
||||
mode: 'm3u',
|
||||
m3u: './snd/play.m3u'
|
||||
})});</script>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
Javascript is required to use the MP3 player.
|
||||
Please choose of the alternatives listed below.
|
||||
</noscript>
|
||||
</body>
|
||||
</html>
|
23
demo/mp3url.html
Normal file
@ -0,0 +1,23 @@
|
||||
<html>
|
||||
<head>
|
||||
<base href="." />
|
||||
|
||||
<title>MyPlayer mp3url Demo</title>
|
||||
|
||||
<script type="text/javascript" src="../js/jquery.js"></script>
|
||||
<script type="text/javascript" src="../js/myplayer.min.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="../css/myplayer.css" />
|
||||
|
||||
<script type="text/javascript">$(function(){MyPlayer({
|
||||
mode: 'mp3url',
|
||||
mp3url: './snd/'
|
||||
})});</script>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
Javascript is required to use the MP3 player.
|
||||
Please choose of the alternatives listed below.
|
||||
</noscript>
|
||||
</body>
|
||||
</html>
|
24
demo/network.html
Normal file
@ -0,0 +1,24 @@
|
||||
<html>
|
||||
<head>
|
||||
<base href="." />
|
||||
|
||||
<title>MyPlayer M3U With Streams Demo</title>
|
||||
|
||||
<script type="text/javascript" src="../js/jquery.js"></script>
|
||||
<script type="text/javascript" src="../js/myplayer.min.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="../css/myplayer.css" />
|
||||
|
||||
<script type="text/javascript">$(function(){MyPlayer({
|
||||
mode: 'm3u',
|
||||
m3u: './snd/network.m3u',
|
||||
network: true
|
||||
})});</script>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
Javascript is required to use the MP3 player.
|
||||
Please choose of the alternatives listed below.
|
||||
</noscript>
|
||||
</body>
|
||||
</html>
|
10
demo/php/.htaccess
Normal file
@ -0,0 +1,10 @@
|
||||
RewriteEngine on
|
||||
|
||||
# (as suggested by www.zeilenwechsel.de)
|
||||
|
||||
RewriteBase /
|
||||
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond $1#%{REQUEST_URI} ([^#]*)#(.*)\1$
|
||||
RewriteRule ^(.*)$ %2index.php/$1 [QSA,L]
|
||||
|
7
demo/php/include/config.inc.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
$waveform = array(
|
||||
'snddir' => dirname(__FILE__).'/../../snd',
|
||||
'cachedir' => dirname(__FILE__).'/../../tmp'
|
||||
);
|
||||
|
18
demo/php/include/functions.inc.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
function fatal_error($msg, $status = '505 Internal Server Error') {
|
||||
header('Status: '.$status);
|
||||
|
||||
echo $msg."\n";
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
function sanitize_path_request($path_info) {
|
||||
return preg_replace(
|
||||
array('|^/|', '/[^A-Za-z0-9\-\.]/'),
|
||||
array('', ''),
|
||||
$path_info
|
||||
);
|
||||
}
|
||||
|
5
demo/php/include/init.inc.php
Normal file
@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once('config.inc.php');
|
||||
require_once('functions.inc.php');
|
||||
|
32
demo/php/index.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
set_include_path(dirname(__FILE__).'/include');
|
||||
|
||||
require_once('init.inc.php');
|
||||
|
||||
$path = sanitize_path_request($_SERVER['PATH_INFO']);
|
||||
|
||||
$cachefile = $waveform['cachedir'].'/'.sha1($path);
|
||||
|
||||
$mp3file = $waveform['snddir'].'/'.$path;
|
||||
|
||||
if(!is_file($mp3file))
|
||||
exit(fatal_error("Error: requested file $mp3file not found"));
|
||||
|
||||
if(!file_exists($cachefile)) {
|
||||
$cmdline = 'waveform draw "'.$mp3file.'" "'.$cachefile.'" 0 -1';
|
||||
$system_rv = null;
|
||||
|
||||
system($cmdline, $system_rv);
|
||||
|
||||
if($system_rv!=0) {
|
||||
if(file_Exists($cachefile))
|
||||
unlink($cachefile);
|
||||
|
||||
exit(fatal_error('Error: generating the waveform diagram failed'));
|
||||
}
|
||||
}
|
||||
|
||||
header('Content-type: image/jpeg');
|
||||
|
||||
echo file_get_contents($cachefile);
|
||||
|
23
demo/relative-m3u.html
Normal file
@ -0,0 +1,23 @@
|
||||
<html>
|
||||
<head>
|
||||
<base href="." />
|
||||
|
||||
<title>MyPlayer M3U (Relative Entries) Demo</title>
|
||||
|
||||
<script type="text/javascript" src="../js/jquery.js"></script>
|
||||
<script type="text/javascript" src="../js/myplayer.min.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="../css/myplayer.css" />
|
||||
|
||||
<script type="text/javascript">$(function(){MyPlayer({
|
||||
mode: 'm3u',
|
||||
m3u: './snd/relative.m3u'
|
||||
})});</script>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
Javascript is required to use the MP3 player.
|
||||
Please choose of the alternatives listed below.
|
||||
</noscript>
|
||||
</body>
|
||||
</html>
|
3
demo/snd/.htaccess
Normal file
@ -0,0 +1,3 @@
|
||||
Options +Indexes
|
||||
AddType audio/ogg .ogg
|
||||
AddType audio/mpeg .mp3
|
BIN
demo/snd/dreamz.mp3
Executable file
5
demo/snd/network.m3u
Normal file
@ -0,0 +1,5 @@
|
||||
#EXTM3U
|
||||
#EXTINF:-1,NoLife-radio
|
||||
http://37.187.79.56:2868/stream
|
||||
#EXTINF:-1,ZaycevFM (128k)
|
||||
http://radio.zaycev.fm:8999/ZaycevFM(128)
|
3
demo/snd/play.extm3u
Normal file
@ -0,0 +1,3 @@
|
||||
#EXTM3U
|
||||
#EXTINF:59, tilt - Dreamz
|
||||
dreamz.mp3
|
1
demo/snd/play.m3u
Normal file
@ -0,0 +1 @@
|
||||
snd/dreamz.mp3
|
1
demo/snd/relative.m3u
Normal file
@ -0,0 +1 @@
|
||||
dreamz.mp3
|
24
demo/stream-m3u.html
Normal file
@ -0,0 +1,24 @@
|
||||
<html>
|
||||
<head>
|
||||
<base href="." />
|
||||
|
||||
<title>MyPlayer M3U With Streams Demo</title>
|
||||
|
||||
<script type="text/javascript" src="../js/jquery.js"></script>
|
||||
<script type="text/javascript" src="../js/myplayer.min.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="../css/myplayer.css" />
|
||||
|
||||
<script type="text/javascript">$(function(){MyPlayer({
|
||||
mode: 'm3u',
|
||||
m3u: './snd/streaming.m3u',
|
||||
filematch: /./
|
||||
})});</script>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
Javascript is required to use the MP3 player.
|
||||
Please choose of the alternatives listed below.
|
||||
</noscript>
|
||||
</body>
|
||||
</html>
|
24
demo/types.html
Normal file
@ -0,0 +1,24 @@
|
||||
<html>
|
||||
<head>
|
||||
<base href="." />
|
||||
|
||||
<title>MyPlayer types Demo</title>
|
||||
|
||||
<script type="text/javascript" src="../js/jquery.js"></script>
|
||||
<script type="text/javascript" src="../js/myplayer.min.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="../css/myplayer.css" />
|
||||
|
||||
<script type="text/javascript">$(function(){MyPlayer({
|
||||
mode: 'm3u',
|
||||
m3u: './snd/play.m3u',
|
||||
types: ['ogg']
|
||||
})});</script>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
Javascript is required to use the MP3 player.
|
||||
Please choose of the alternatives listed below.
|
||||
</noscript>
|
||||
</body>
|
||||
</html>
|
27
demo/waveform.html
Normal file
@ -0,0 +1,27 @@
|
||||
<html>
|
||||
<head>
|
||||
<base href="." />
|
||||
|
||||
<title>MyPlayer M3U Demo</title>
|
||||
|
||||
<script type="text/javascript" src="../js/jquery.js"></script>
|
||||
<script type="text/javascript" src="../js/myplayer.min.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="../css/myplayer.css" />
|
||||
|
||||
<script type="text/javascript">$(function(){MyPlayer({
|
||||
mode: 'list',
|
||||
waveform: true,
|
||||
list: [
|
||||
{ url: './snd/dreamz.mp3',
|
||||
title: 'tilt - Dreamz' }
|
||||
]
|
||||
})});</script>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
Javascript is required to use the MP3 player.
|
||||
Please choose of the alternatives listed below.
|
||||
</noscript>
|
||||
</body>
|
||||
</html>
|
44
index.html
Normal file
@ -0,0 +1,44 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>MyPlayer - An Audio Player for the Web with Playlist and ID3 Support</title>
|
||||
<link rel="stylesheet" href="css/index.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="home"><a href="http://tk-sls.de">//tk-sls.de</a></div>
|
||||
<h1> MyPlayer</h1>
|
||||
|
||||
<p>An audio player (mp3, ogg) for the web with M3U-playlist and ID3-support.</p>
|
||||
|
||||
<p>Based on mediaelement.js. MIT-licensed. Cooks coffee (almost).</p>
|
||||
|
||||
<h2>About:</h2>
|
||||
|
||||
<p>This project provides a JavaScript constructor <tt>MyPlayer({...options...})</tt> that can be used
|
||||
to embed lists of audio files as read from an index document or an M3U into a web document.</p>
|
||||
|
||||
<p>They will be displayed in a playback GUI with a playlist that can optionally be filled
|
||||
from the "title" and "artist" values of the files' ID3 tags (v1 and v2 are supported).</p>
|
||||
|
||||
<p>The player is "detachable", meaning the user can open it in a new window,
|
||||
preventing that playback breaks when the user leaves the page.</p>
|
||||
|
||||
<h2>Resources:</h2>
|
||||
|
||||
<p>Documentation & Examples: <a href="demo/index.html">demo/index.html</a></p>
|
||||
|
||||
<p>Current release is: 11-20-2015</p>
|
||||
|
||||
<p>Download URL (latest tarball): <a title="MyPlayer Download (.tar.gz)" href="http://tk-sls.de/ref/myplayer.dist.tar.gz">http://tk-sls.de/ref/myplayer.dist.tar.gz</a></p>
|
||||
|
||||
<p>Project website: <a title="MyPlayer Project Website" href="http://tk-sls.de/ref/myplayer/">http://tk-sls.de/ref/myplayer/</a></p>
|
||||
|
||||
<h2>Additional Reading:</h2>
|
||||
|
||||
<p>License: <a href="LICENSE.txt">MIT</a>.</p>
|
||||
<p>See <a href="README.txt">README.txt</a> for further information.</p>
|
||||
|
||||
<h2>Author Contact:</h2>
|
||||
|
||||
<p>Please send questions to: tilt at linuxfoo dot de</p>
|
||||
</body>
|
||||
</html>
|
9597
js/jquery.js
vendored
Normal file
231
js/myplayer.min.js
vendored
Normal file
@ -0,0 +1,231 @@
|
||||
/*
|
||||
jQuery
|
||||
Copyright 2014 jQuery Foundation and other contributors
|
||||
http://jquery.com/
|
||||
MediaElement.js
|
||||
Copyright 2010-2013, John Dyer (http://j.hn)
|
||||
MediaElement Playlist Feature (plugin) -
|
||||
Andrew Berezovsky <andrew.berezovsky@gmail.com>
|
||||
and Junaid Qadir Baloch <shekhanzai.baloch@gmail.com>
|
||||
JavaScript-ID3-Reader
|
||||
Copyright (c) 2008 Jacob Seidelin, http://blog.nihilogic.dk/ BSD License
|
||||
Copyright (c) 2009 Opera Software ASA BSD License
|
||||
Copyright (c) 2010 António Afonso BSD License
|
||||
Copyright (c) 2010 Joshua Kifer BSD License
|
||||
MyPlayer
|
||||
Copyright (c) 2014 tilt@linuxfoo.de MIT License
|
||||
*/
|
||||
var mejs=mejs||{};mejs.version="2.18.2";mejs.meIndex=0;
|
||||
mejs.plugins={silverlight:[{version:[3,0],types:"video/mp4 video/m4v video/mov video/wmv audio/wma audio/m4a audio/mp3 audio/wav audio/mpeg".split(" ")}],flash:[{version:[9,0,124],types:"video/mp4 video/m4v video/mov video/flv video/rtmp video/x-flv audio/flv audio/x-flv audio/mp3 audio/m4a audio/mpeg video/youtube video/x-youtube video/dailymotion video/x-dailymotion application/x-mpegURL".split(" ")}],youtube:[{version:null,types:["video/youtube","video/x-youtube","audio/youtube","audio/x-youtube"]}],
|
||||
vimeo:[{version:null,types:["video/vimeo","video/x-vimeo"]}]};
|
||||
mejs.Utility={encodeUrl:function(c){return encodeURIComponent(c)},escapeHTML:function(c){return c.toString().split("&").join("&").split("<").join("<").split('"').join(""")},absolutizeUrl:function(c){var a=document.createElement("div");return a.innerHTML='<a href="'+this.escapeHTML(c)+'">x</a>',a.firstChild.href},getScriptPath:function(c){for(var a,b,f,e,d,g=0,h="",k="",l=document.getElementsByTagName("script"),n=l.length,m=c.length;n>g;g++){f=l[g].src;a=f.lastIndexOf("/");-1<a?(d=f.substring(a+
|
||||
1),e=f.substring(0,a+1)):(d=f,e="");for(a=0;m>a;a++)if(k=c[a],b=d.indexOf(k),-1<b){h=e;break}if(""!==h)break}return h},calculateTimeFormat:function(c,a,b){0>c&&(c=0);"undefined"==typeof b&&(b=25);var f=a.timeFormat,e=f[0],d=f[1]==f[0],g=d?2:1,h=":",k=Math.floor(c/3600)%24,l=Math.floor(c/60)%60,n=Math.floor(c%60);c=[[Math.floor((c%1*b).toFixed(3)),"f"],[n,"s"],[l,"m"],[k,"h"]];f.length<g&&(h=f[g]);g=!1;b=0;for(k=c.length;k>b;b++)if(-1!==f.indexOf(c[b][1]))g=!0;else if(g){l=!1;for(n=b;k>n;n++)if(0<
|
||||
c[n][0]){l=!0;break}if(!l)break;d||(f=e+f);f=c[b][1]+h+f;d&&(f=c[b][1]+f);e=c[b][1]}a.currentTimeFormat=f},twoDigitsString:function(c){return 10>c?"0"+c:String(c)},secondsToTimeCode:function(c,a,b,f){if(0>c&&(c=0),"object"!=typeof a)a=a?"hh:mm:ss":"m:ss",a={currentTimeFormat:b?a+":ff":a,framesPerSecond:f||25};b=a.framesPerSecond;"undefined"==typeof b&&(b=25);a=a.currentTimeFormat;f=Math.floor(c/3600)%24;var e=Math.floor(c/60)%60,d=Math.floor(c%60);lis=[[Math.floor((c%1*b).toFixed(3)),"f"],[d,"s"],
|
||||
[e,"m"],[f,"h"]];c=a;i=0;for(len=lis.length;i<len;i++)c=c.replace(lis[i][1]+lis[i][1],this.twoDigitsString(lis[i][0])),c=c.replace(lis[i][1],lis[i][0]);return c},timeCodeToSeconds:function(c,a,b,f){"undefined"==typeof b?b=!1:"undefined"==typeof f&&(f=25);c=c.split(":");a=parseInt(c[0],10);var e=parseInt(c[1],10),d=parseInt(c[2],10),g=0;return b&&(g=parseInt(c[3])/f),3600*a+60*e+d+g},convertSMPTEtoSeconds:function(c){if("string"!=typeof c)return!1;c=c.replace(",",".");var a=0,b=-1!=c.indexOf(".")?
|
||||
c.split(".")[1].length:0,f=1;c=c.split(":").reverse();for(var e=0;e<c.length;e++)f=1,0<e&&(f=Math.pow(60,e)),a+=Number(c[e])*f;return Number(a.toFixed(b))},removeSwf:function(c){var a=document.getElementById(c);a&&/object|embed/i.test(a.nodeName)&&(mejs.MediaFeatures.isIE?(a.style.display="none",function(){4==a.readyState?mejs.Utility.removeObjectInIE(c):setTimeout(arguments.callee,10)}()):a.parentNode.removeChild(a))},removeObjectInIE:function(c){if(c=document.getElementById(c)){for(var a in c)"function"==
|
||||
typeof c[a]&&(c[a]=null);c.parentNode.removeChild(c)}}};
|
||||
mejs.PluginDetector={hasPluginVersion:function(c,a){var b=this.plugins[c];return a[1]=a[1]||0,a[2]=a[2]||0,b[0]>a[0]||b[0]==a[0]&&b[1]>a[1]||b[0]==a[0]&&b[1]==a[1]&&b[2]>=a[2]?!0:!1},nav:window.navigator,ua:window.navigator.userAgent.toLowerCase(),plugins:[],addPlugin:function(c,a,b,f,e){this.plugins[c]=this.detectPlugin(a,b,f,e)},detectPlugin:function(c,a,b,f){var e,d,g=[0,0,0];if("undefined"!=typeof this.nav.plugins&&"object"==typeof this.nav.plugins[c]){if(e=this.nav.plugins[c].description,e&&
|
||||
("undefined"==typeof this.nav.mimeTypes||!this.nav.mimeTypes[a]||this.nav.mimeTypes[a].enabledPlugin))for(g=e.replace(c,"").replace(/^\s+/,"").replace(/\sr/gi,".").split("."),c=0;c<g.length;c++)g[c]=parseInt(g[c].match(/\d+/),10)}else if("undefined"!=typeof window.ActiveXObject)try{(d=new ActiveXObject(b))&&(g=f(d))}catch(h){}return g}};
|
||||
mejs.PluginDetector.addPlugin("flash","Shockwave Flash","application/x-shockwave-flash","ShockwaveFlash.ShockwaveFlash",function(c){var a=[];c=c.GetVariable("$version");return c&&(c=c.split(" ")[1].split(","),a=[parseInt(c[0],10),parseInt(c[1],10),parseInt(c[2],10)]),a});
|
||||
mejs.PluginDetector.addPlugin("silverlight","Silverlight Plug-In","application/x-silverlight-2","AgControl.AgControl",function(c){var a=[0,0,0,0],b=function(a,b,d,c){for(;a.isVersionSupported(b[0]+"."+b[1]+"."+b[2]+"."+b[3]);)b[d]+=c;b[d]-=c};return b(c,a,0,1),b(c,a,1,1),b(c,a,2,1E4),b(c,a,2,1E3),b(c,a,2,100),b(c,a,2,10),b(c,a,2,1),b(c,a,3,1),a});
|
||||
mejs.MediaFeatures={init:function(){var c,a,b=this,f=document;c=mejs.PluginDetector.nav;var e=mejs.PluginDetector.ua.toLowerCase(),d=["source","track","audio","video"];b.isiPad=null!==e.match(/ipad/i);b.isiPhone=null!==e.match(/iphone/i);b.isiOS=b.isiPhone||b.isiPad;b.isAndroid=null!==e.match(/android/i);b.isBustedAndroid=null!==e.match(/android 2\.[12]/);b.isBustedNativeHTTPS="https:"===location.protocol&&(null!==e.match(/android [12]\./)||null!==e.match(/macintosh.* version.* safari/));b.isIE=-1!=
|
||||
c.appName.toLowerCase().indexOf("microsoft")||null!==c.appName.toLowerCase().match(/trident/gi);b.isChrome=null!==e.match(/chrome/gi);b.isChromium=null!==e.match(/chromium/gi);b.isFirefox=null!==e.match(/firefox/gi);b.isWebkit=null!==e.match(/webkit/gi);b.isGecko=null!==e.match(/gecko/gi)&&!b.isWebkit&&!b.isIE;b.isOpera=null!==e.match(/opera/gi);b.hasTouch="ontouchstart"in window;b.svg=!!document.createElementNS&&!!document.createElementNS("http://www.w3.org/2000/svg","svg").createSVGRect;for(c=0;c<
|
||||
d.length;c++)a=document.createElement(d[c]);b.supportsMediaTag="undefined"!=typeof a.canPlayType||b.isBustedAndroid;try{a.canPlayType("video/mp4")}catch(g){b.supportsMediaTag=!1}b.hasSemiNativeFullScreen="undefined"!=typeof a.webkitEnterFullscreen;b.hasNativeFullscreen="undefined"!=typeof a.requestFullscreen;b.hasWebkitNativeFullScreen="undefined"!=typeof a.webkitRequestFullScreen;b.hasMozNativeFullScreen="undefined"!=typeof a.mozRequestFullScreen;b.hasMsNativeFullScreen="undefined"!=typeof a.msRequestFullscreen;
|
||||
b.hasTrueNativeFullScreen=b.hasWebkitNativeFullScreen||b.hasMozNativeFullScreen||b.hasMsNativeFullScreen;b.nativeFullScreenEnabled=b.hasTrueNativeFullScreen;b.hasMozNativeFullScreen?b.nativeFullScreenEnabled=document.mozFullScreenEnabled:b.hasMsNativeFullScreen&&(b.nativeFullScreenEnabled=document.msFullscreenEnabled);b.isChrome&&(b.hasSemiNativeFullScreen=!1);b.hasTrueNativeFullScreen&&(b.fullScreenEventName="",b.hasWebkitNativeFullScreen?b.fullScreenEventName="webkitfullscreenchange":b.hasMozNativeFullScreen?
|
||||
b.fullScreenEventName="mozfullscreenchange":b.hasMsNativeFullScreen&&(b.fullScreenEventName="MSFullscreenChange"),b.isFullScreen=function(){return b.hasMozNativeFullScreen?f.mozFullScreen:b.hasWebkitNativeFullScreen?f.webkitIsFullScreen:b.hasMsNativeFullScreen?null!==f.msFullscreenElement:void 0},b.requestFullScreen=function(a){b.hasWebkitNativeFullScreen?a.webkitRequestFullScreen():b.hasMozNativeFullScreen?a.mozRequestFullScreen():b.hasMsNativeFullScreen&&a.msRequestFullscreen()},b.cancelFullScreen=
|
||||
function(){b.hasWebkitNativeFullScreen?document.webkitCancelFullScreen():b.hasMozNativeFullScreen?document.mozCancelFullScreen():b.hasMsNativeFullScreen&&document.msExitFullscreen()});b.hasSemiNativeFullScreen&&e.match(/mac os x 10_5/i)&&(b.hasNativeFullScreen=!1,b.hasSemiNativeFullScreen=!1)}};mejs.MediaFeatures.init();
|
||||
mejs.HtmlMediaElement={pluginType:"native",isFullScreen:!1,setCurrentTime:function(c){this.currentTime=c},setMuted:function(c){this.muted=c},setVolume:function(c){this.volume=c},stop:function(){this.pause()},setSrc:function(c){for(var a=this.getElementsByTagName("source");0<a.length;)this.removeChild(a[0]);if("string"==typeof c)this.src=c;else for(var b,a=0;a<c.length;a++)if(b=c[a],this.canPlayType(b.type)){this.src=b.src;break}},setVideoSize:function(c,a){this.width=c;this.height=a}};
|
||||
mejs.PluginMediaElement=function(c,a,b){this.id=c;this.pluginType=a;this.src=b;this.events={};this.attributes={}};
|
||||
mejs.PluginMediaElement.prototype={pluginElement:null,pluginType:"",isFullScreen:!1,playbackRate:-1,defaultPlaybackRate:-1,seekable:[],played:[],paused:!0,ended:!1,seeking:!1,duration:0,error:null,tagName:"",muted:!1,volume:1,currentTime:0,play:function(){null!=this.pluginApi&&("youtube"==this.pluginType||"vimeo"==this.pluginType?this.pluginApi.playVideo():this.pluginApi.playMedia(),this.paused=!1)},load:function(){null!=this.pluginApi&&("youtube"==this.pluginType||"vimeo"==this.pluginType||this.pluginApi.loadMedia(),
|
||||
this.paused=!1)},pause:function(){null!=this.pluginApi&&("youtube"==this.pluginType||"vimeo"==this.pluginType?this.pluginApi.pauseVideo():this.pluginApi.pauseMedia(),this.paused=!0)},stop:function(){null!=this.pluginApi&&("youtube"==this.pluginType||"vimeo"==this.pluginType?this.pluginApi.stopVideo():this.pluginApi.stopMedia(),this.paused=!0)},canPlayType:function(c){var a,b,f,e=mejs.plugins[this.pluginType];for(a=0;a<e.length;a++)if(f=e[a],mejs.PluginDetector.hasPluginVersion(this.pluginType,f.version))for(b=
|
||||
0;b<f.types.length;b++)if(c==f.types[b])return"probably";return""},positionFullscreenButton:function(c,a,b){null!=this.pluginApi&&this.pluginApi.positionFullscreenButton&&this.pluginApi.positionFullscreenButton(Math.floor(c),Math.floor(a),b)},hideFullscreenButton:function(){null!=this.pluginApi&&this.pluginApi.hideFullscreenButton&&this.pluginApi.hideFullscreenButton()},setSrc:function(c){if("string"==typeof c)this.pluginApi.setSrc(mejs.Utility.absolutizeUrl(c)),this.src=mejs.Utility.absolutizeUrl(c);
|
||||
else{var a,b;for(a=0;a<c.length;a++)if(b=c[a],this.canPlayType(b.type)){this.pluginApi.setSrc(mejs.Utility.absolutizeUrl(b.src));this.src=mejs.Utility.absolutizeUrl(b.src);break}}},setCurrentTime:function(c){null!=this.pluginApi&&("youtube"==this.pluginType||"vimeo"==this.pluginType?this.pluginApi.seekTo(c):this.pluginApi.setCurrentTime(c),this.currentTime=c)},setVolume:function(c){null!=this.pluginApi&&("youtube"==this.pluginType?this.pluginApi.setVolume(100*c):this.pluginApi.setVolume(c),this.volume=
|
||||
c)},setMuted:function(c){null!=this.pluginApi&&("youtube"==this.pluginType?(c?this.pluginApi.mute():this.pluginApi.unMute(),this.muted=c,this.dispatchEvent({type:"volumechange"})):this.pluginApi.setMuted(c),this.muted=c)},setVideoSize:function(c,a){this.pluginElement&&this.pluginElement.style&&(this.pluginElement.style.width=c+"px",this.pluginElement.style.height=a+"px");null!=this.pluginApi&&this.pluginApi.setVideoSize&&this.pluginApi.setVideoSize(c,a)},setFullscreen:function(c){null!=this.pluginApi&&
|
||||
this.pluginApi.setFullscreen&&this.pluginApi.setFullscreen(c)},enterFullScreen:function(){null!=this.pluginApi&&this.pluginApi.setFullscreen&&this.setFullscreen(!0)},exitFullScreen:function(){null!=this.pluginApi&&this.pluginApi.setFullscreen&&this.setFullscreen(!1)},addEventListener:function(c,a,b){this.events[c]=this.events[c]||[];this.events[c].push(a)},removeEventListener:function(c,a){if(!c)return this.events={},!0;var b=this.events[c];if(!b)return!0;if(!a)return this.events[c]=[],!0;for(var f=
|
||||
0;f<b.length;f++)if(b[f]===a)return this.events[c].splice(f,1),!0;return!1},dispatchEvent:function(c){var a,b=this.events[c.type];if(b)for(a=0;a<b.length;a++)b[a].apply(this,[c])},hasAttribute:function(c){return c in this.attributes},removeAttribute:function(c){delete this.attributes[c]},getAttribute:function(c){return this.hasAttribute(c)?this.attributes[c]:""},setAttribute:function(c,a){this.attributes[c]=a},remove:function(){mejs.Utility.removeSwf(this.pluginElement.id);mejs.MediaPluginBridge.unregisterPluginElement(this.pluginElement.id)}};
|
||||
mejs.MediaPluginBridge={pluginMediaElements:{},htmlMediaElements:{},registerPluginElement:function(c,a,b){this.pluginMediaElements[c]=a;this.htmlMediaElements[c]=b},unregisterPluginElement:function(c){delete this.pluginMediaElements[c];delete this.htmlMediaElements[c]},initPlugin:function(c){var a=this.pluginMediaElements[c],b=this.htmlMediaElements[c];if(a){switch(a.pluginType){case "flash":a.pluginElement=a.pluginApi=document.getElementById(c);break;case "silverlight":a.pluginElement=document.getElementById(a.id),
|
||||
a.pluginApi=a.pluginElement.Content.MediaElementJS}null!=a.pluginApi&&a.success&&a.success(a,b)}},fireEvent:function(c,a,b){var f,e;if(c=this.pluginMediaElements[c]){a={type:a,target:c};for(f in b)c[f]=b[f],a[f]=b[f];e=b.bufferedTime||0;a.target.buffered=a.buffered={start:function(a){return 0},end:function(a){return e},length:1};c.dispatchEvent(a)}}};
|
||||
mejs.MediaElementDefaults={mode:"auto",plugins:["flash","silverlight","youtube","vimeo"],enablePluginDebug:!1,httpsBasicAuthSite:!1,type:"",pluginPath:mejs.Utility.getScriptPath(["mediaelement.js","mediaelement.min.js","mediaelement-and-player.js","mediaelement-and-player.min.js"]),flashName:"flashmediaelement.swf",flashStreamer:"",flashScriptAccess:"sameDomain",enablePluginSmoothing:!1,enablePseudoStreaming:!1,pseudoStreamingStartQueryParam:"start",silverlightName:"silverlightmediaelement.xap",defaultVideoWidth:480,
|
||||
defaultVideoHeight:270,pluginWidth:-1,pluginHeight:-1,pluginVars:[],timerRate:250,startVolume:.8,success:function(){},error:function(){}};mejs.MediaElement=function(c,a){return mejs.HtmlMediaElementShim.create(c,a)};
|
||||
mejs.HtmlMediaElementShim={create:function(c,a){var b,f,e={},d="string"==typeof c?document.getElementById(c):c,g=d.tagName.toLowerCase(),h=(g="audio"===g||"video"===g)?d.getAttribute("src"):d.getAttribute("href"),k=d.getAttribute("poster"),l=d.getAttribute("autoplay"),n=d.getAttribute("preload"),m=d.getAttribute("controls");for(f in mejs.MediaElementDefaults)e[f]=mejs.MediaElementDefaults[f];for(f in a)e[f]=a[f];return h="undefined"==typeof h||null===h||""==h?null:h,k="undefined"==typeof k||null===
|
||||
k?"":k,n="undefined"==typeof n||null===n||"false"===n?"none":n,l=!("undefined"==typeof l||null===l||"false"===l),m=!("undefined"==typeof m||null===m||"false"===m),b=this.determinePlayback(d,e,mejs.MediaFeatures.supportsMediaTag,g,h),b.url=null!==b.url?mejs.Utility.absolutizeUrl(b.url):"","native"==b.method?(mejs.MediaFeatures.isBustedAndroid&&(d.src=b.url,d.addEventListener("click",function(){d.play()},!1)),this.updateNative(b,e,l,n)):""!==b.method?this.createPlugin(b,e,k,l,n,m):(this.createErrorMessage(b,
|
||||
e,k),this)},determinePlayback:function(c,a,b,f,e){var d,g,h,k,l,n,m=[],p={method:"",url:"",htmlMediaElement:c,isVideo:"audio"!=c.tagName.toLowerCase()};if("undefined"!=typeof a.type&&""!==a.type)if("string"==typeof a.type)m.push({type:a.type,url:e});else for(d=0;d<a.type.length;d++)m.push({type:a.type[d],url:e});else if(null!==e)h=this.formatType(e,c.getAttribute("type")),m.push({type:h,url:e});else for(d=0;d<c.childNodes.length;d++)g=c.childNodes[d],1==g.nodeType&&"source"==g.tagName.toLowerCase()&&
|
||||
(e=g.getAttribute("src"),h=this.formatType(e,g.getAttribute("type")),n=g.getAttribute("media"),(!n||!window.matchMedia||window.matchMedia&&window.matchMedia(n).matches)&&m.push({type:h,url:e}));if(!f&&0<m.length&&null!==m[0].url&&-1<this.getTypeFromFile(m[0].url).indexOf("audio")&&(p.isVideo=!1),mejs.MediaFeatures.isBustedAndroid&&(c.canPlayType=function(a){return null!==a.match(/video\/(mp4|m4v)/gi)?"maybe":""}),mejs.MediaFeatures.isChromium&&(c.canPlayType=function(a){return null!==a.match(/video\/(webm|ogv|ogg)/gi)?
|
||||
"maybe":""}),!(!b||"auto"!==a.mode&&"auto_plugin"!==a.mode&&"native"!==a.mode||mejs.MediaFeatures.isBustedNativeHTTPS&&!0===a.httpsBasicAuthSite)){f||(l=document.createElement(p.isVideo?"video":"audio"),c.parentNode.insertBefore(l,c),c.style.display="none",p.htmlMediaElement=c=l);for(d=0;d<m.length;d++)if("video/m3u8"==m[d].type||""!==c.canPlayType(m[d].type).replace(/no/,"")||""!==c.canPlayType(m[d].type.replace(/mp3/,"mpeg")).replace(/no/,"")||""!==c.canPlayType(m[d].type.replace(/m4a/,"mp4")).replace(/no/,
|
||||
"")){p.method="native";p.url=m[d].url;break}if("native"===p.method&&(null!==p.url&&(c.src=p.url),"auto_plugin"!==a.mode))return p}if("auto"===a.mode||"auto_plugin"===a.mode||"shim"===a.mode)for(d=0;d<m.length;d++)for(h |