[PYTHON] Erstelle deinen eigenen Musik-Player mit Bottle0.13 + jPlayer2.5!

Einführung

Das leichte Framework Bottle scheint beliebt zu sein, daher werde ich einen Cloud-Musik-Player zum Üben erstellen. Das fertige Produkt ist in Bitbucket aufgeführt, sodass nur die wichtigsten Punkte erläutert werden. Das Operationsbeispiel finden Sie unter hier. Übrigens habe ich den Vorgang mit Python 2.6 bestätigt.

Was ist ein Cloud Music Player?

Es ist praktisch, nach dem Kauf von jedem Gerät wie iTunes oder Amazon Cloud Player herunterladen und abspielen zu können. Als CD-Kaufküche möchte ich sie jedoch immer noch mit der vorliegenden Soundquellendatei abspielen. Mit Google Music können Sie Dateien selbst hochladen, aber die japanische Musikindustrie ist unflexibel Daher wird es vorerst schwierig sein, einen ähnlichen Dienst in Japan zu betreiben. Aus diesem Grund wollte ich immer meinen eigenen Cloud-Musik-Player erstellen, daher werde ich diese Gelegenheit nutzen, um ihn zu implementieren.

Überlegen Sie, wie es funktioniert

Eine weitere Option ist das Erstellen eines Streaming-Servers mit Subsonic oder Icecast. Dies ist zwar einfach und kann von vielen Spielern abgespielt werden, hat jedoch den Nachteil, dass eine Verarbeitungslast entsteht, da die Tonquelle auf der Serverseite codiert ist. (Tatsächlich habe ich diese Methode bis jetzt verwendet, aber es gibt ein Problem mit der Songauswahl.) Dieses Mal wird der größte Teil der Wiedergabe dem jQuery-Plug-In jPlayer überlassen, einem HTML5-basierten Mediaplayer. Ich weiß nicht, ob das leichte Framework Bottle ins Spiel kommt, da der Verarbeitungsteil von stumpfen Python nur darin besteht, die Wiedergabeliste aufzulisten, aber ich denke, es ist genau richtig zum Lernen.

Flaschengrundlagen

Mit Bottle können Sie Web-Apps mit einer wirklich einfachen Syntax erstellen.

au.py


# -*- coding: utf-8 -*-
from bottle import route, run #Es scheint üblich zu sein, nur die erforderlichen Methoden abzurufen (?)

@route('/hello') #Geben Sie den Zielpfad an, um die folgende Funktion auszuführen
def hello(): #Der Funktionsname kann beliebig sein
    return 'Hello World!' #Inhalt, der an den Browser ausgegeben werden soll

if __name__ == "__main__": #Beachten Sie, dass, wenn Sie es nicht blockieren, ein Fehler auftritt, wenn Sie es von Apache ausführen, das später beschrieben wird.
    run(host='0.0.0.0', port=8080, debug=True, reloader=True)

Für das Argument von run ()

Führen Sie das obige Skript über die Befehlszeile aus.

python au.py

Wenn Sie über Ihren Browser auf http: // Serveradresse: 8080 / Hallo zugreifen, sollte "Hallo Welt!" Angezeigt werden.

Verwenden Sie eine Vorlage

Lassen Sie uns nun den gewünschten Cloud-Musik-Player von hier aus implementieren. Die Template-Engine von Bottle kann wie Django verwendet werden, daher sollten erfahrene Django-Benutzer diese gerne problemlos verwenden. Detaillierte Spezifikationen finden Sie im Originaldokument.

au.py


from bottle import route, template, TEMPLATE_PATH
import os

ROOT_PATH = os.path.dirname(os.path.abspath(__file__)) #Absoluter Pfad zu dem Ordner, in dem sich dieses Skript befindet
TEMPLATE_PATH.insert(0, ROOT_PATH+'/templates') #Geben Sie den Ordner an, in dem die Vorlagendatei gespeichert werden soll

@route('/')
def index():
    return template('player.html') #Sie können auch Parameter übergeben, die der Vorlagendatei folgen

In der Vorlage bereiten wir jPlayer sofort vor. Da das Erscheinungsbild zweitrangig ist, verwendet CSS [Blue Monday], das mit jPlayer geliefert wird, und der HTML-Teil ist ein Voice-Player mit einer Wiedergabeliste von dieser Site. Ich durfte mich beziehen! Außerdem werden die gemeinsamen Teile jeder Vorlage in einer separaten Vorlagendatei mit `% rebase ()` zusammengefasst. Beachten Sie, dass dies ein anderes Format als Django hat. Bitte beachten Sie, dass die in den Parametern übergebenen `jplayer.m3u.js `und`` init.js``` Skripte sind, die Sie später erstellen werden.

templates/player.html


% rebase('base.html', css=['jplayer.blue.monday.css'], js=['jquery.jplayer.min.js', 'jplayer.playlist.min.js', 'jplayer.m3u.js', 'init.js']) <!--Da Parameter nach der Vorlagendatei übergeben werden können, geben Sie die CSS- und JS-Dateien an, die zusätzlich gelesen werden sollen.-->
<div id="jquery_jplayer_N" class="jp-jplayer"></div>
<div id="jp_container_N" class="jp-audio">
    <div class="jp-type-playlist">
        <div class="jp-gui jp-interface">
            <ul class="jp-controls">
                <li><a href="javascript:;" class="jp-previous" tabindex="1">previous</a></li>
                <li><a href="javascript:;" class="jp-play" tabindex="1">play</a></li>
                <li><a href="javascript:;" class="jp-pause" tabindex="1">pause</a></li>
                <li><a href="javascript:;" class="jp-next" tabindex="1">next</a></li>
                <li><a href="javascript:;" class="jp-stop" tabindex="1">stop</a></li>
                <li><a href="javascript:;" class="jp-mute" tabindex="1" title="mute">mute</a></li>
                <li><a href="javascript:;" class="jp-unmute" tabindex="1" title="unmute">unmute</a></li>
                <li><a href="javascript:;" class="jp-volume-max" tabindex="1" title="max volume">max volume</a></li>
            </ul>
            <div class="jp-progress">
                <div class="jp-seek-bar">
                    <div class="jp-play-bar"></div>
                </div>
            </div>
            <div class="jp-volume-bar">
                <div class="jp-volume-bar-value"></div>
            </div>
            <div class="jp-time-holder">
                <div class="jp-current-time"></div>
                <div class="jp-duration"></div>
            </div>
            <ul class="jp-toggles">
                <li><a href="javascript:;" class="jp-shuffle" tabindex="1" title="shuffle">shuffle</a></li>
                <li><a href="javascript:;" class="jp-shuffle-off" tabindex="1" title="shuffle off">shuffle off</a></li>
                <li><a href="javascript:;" class="jp-repeat" tabindex="1" title="repeat">repeat</a></li>
                <li><a href="javascript:;" class="jp-repeat-off" tabindex="1" title="repeat off">repeat off</a></li>
            </ul>
        </div>
        <div class="jp-playlist">
            <ul>
                <li></li>
            </ul>
        </div>
    </div>
</div>
<div id="m3u_list"></div>

Schreiben Sie als Nächstes die Vorlagendatei für den allgemeinen Teil.

templates/base.html


<!DOCTYPE html>
<html>
<head>
    <title>AuPy - Croud Music Player</title>
    <script type="text/javascript" src="js/jquery.min.js"></script>
% for item in css: <!--Lesen Sie die als Parameter übergebene CSS-Datei-->
    <link rel="stylesheet" type="text/css" href="css/{{item}}"> 
% end
% for item in js: <!--Lesen Sie die JS-Datei, die auch als Parameter übergeben wurde-->
    <script type="text/javascript" src="js/{{item}}"></script>
% end
</head>
<body>
{{!base}} <!--Hier ist der Inhalt der aufrufenden Vorlagendatei-->
</body>
</html>

Derzeit kann ich jPlayer noch nicht ausführen.

Erstellen Sie ein jQuery-Plug-In, das m3u-Dateien liest

Implementieren Sie ein Plug-In, mit dem die Datei m3u / m3u8 auf die jPlayer-Wiedergabeliste gesetzt wird. Es kann als jQuery-Plug-In implementiert werden, indem es in das folgende Format geschrieben wird.

;(function($) {
    $.fn.loadm3u = function (){
        //Inhalte verarbeiten
    }
})(jQuery);

Dieses Mal erstellen wir ein Plug-In, das die folgende Verwendung voraussetzt.

$().loadm3u(m3u Dateipfad,Serverseitiger Pfad des Musikordners,Pfad ersetzt werden(Möglichkeit))


 Das Plug-In hat die Funktion, den zuvor angegebenen Pfad automatisch zu ersetzen. Infolgedessen können die von foobar2000 usw. ausgespuckten m3u / m3u8-Dateien so verwendet werden, wie sie sich im Cloud-Musik-Player befinden.


#### **`js/jplayer.m3u.js`**

;(function($) { $.fn.loadm3u = function (filepath, server_music_dir, local_music_dir){ $.get(filepath, function(data){ //Lassen Sie die m3u-Datei als Argument übergeben var data_array = data.split(/\r\n|\r|\n/); //In der Pause teilen var playlists = []; for (var i = 0; i < data_array.length; i++){ //Zeile für Zeile verarbeiten if(data_array[i] != ""){ if (typeof local_music_dir != "undefined") { data_array[i] = data_array[i].replace(local_music_dir+"\", "") //Entfernen Sie den zu ersetzenden Pfad } unix_dir_path = data_array[i].replace(/\/g, "/") //Korrigieren Sie den Schrägstrich title = unix_dir_path.split("/"); //Mit Schrägstrich teilen playlists.push({"title":title[title.length-1], "free":true, "mp3":server_music_dir+"/"+unix_dir_path}); //Speichern Sie den Dateinamen und den Dateipfad der Tonquelle in der Liste } }

        $("#jquery_jplayer_N").jPlayer("destroy"); //Initialisieren Sie jPlayer

        var Playlist = new jPlayerPlaylist( //Wiedergabelisten und Optionen zum Laden in jPlayer
            {
                jPlayer: "#jquery_jplayer_N",
                cssSelectorAncestor: "#jp_container_N"
            }, playlists, {
                supplied: "mp3" //Unterstützte Audiodateiformate
            }
        );
    });
}

})(jQuery);


 Obwohl im obigen Skript nur mp3 angegeben ist, scheint es, dass es ohne Probleme wiedergegeben wird, selbst wenn Sie eine Musikdatei wie ogg nur für den Dateipfad übergeben. flac hat nicht funktioniert, da der Browser die Wiedergabe nicht unterstützt.

## Generieren Sie eine JS-Datei zur Initialisierung in Python

 Bereiten Sie zunächst ein Skript vor, um die Einstellungen gemeinsam zu beschreiben.


#### **`setting.py`**
```py

#! -*- coding: utf-8 -*-
import os

SERVER_MUSIC_ADDR = os.path.expandvars('audio') #Relativ zu Musikordnern/Absolute URL
SERVER_PLAYLIST_ADDR = os.path.expandvars('playlist') #Relativ zu Wiedergabelistenordnern/Absolute URL
SERVER_PLAYLIST_DIR = os.path.expandvars('/home/example/aupy/playlist') #Absoluter Pfad des Wiedergabelistenordners
LOCAL_MUSIC_DIR = os.path.expandvars('C:\Users\example\Music') #Absoluter Pfad des zu ersetzenden lokalen Musikordners

Listen Sie als Nächstes die Dateien im Wiedergabelistenordner auf dem Server auf, fügen Sie sie zu `` <div id =" m3u_list "> </ div> `hinzu und laden Sie sie in das Plugin, das Sie gerade erstellt haben, wenn der Benutzer auf ein Element klickt. Geben Sie die JS-Datei aus, die in Python ausgegeben werden soll.

au.py


from bottle import route, response
from setting import * #Lesen Sie die Einstellungsdatei

@route('/js/init.js') #Entführen Sie eine Anfrage für diese JS-Datei
def initjs():
    if LOCAL_MUSIC_DIR:
        local_music_dir = ', "'+LOCAL_MUSIC_DIR.replace('\\', '\\\\')+'"' #Legen Sie den zu ersetzenden Pfad fest
    else:
        local_music_dir = ''
    
    output = '$(function(){\n' #Beginnen Sie mit dem Schreiben von Ausgabeinhalten
    files = os.listdir(SERVER_PLAYLIST_DIR) #Listen Sie die Dateien im Wiedergabelistenordner auf
    files.sort()
    flg = True
    for file in files:
        if file.startswith('.'): #.Um htaccess usw. zu überspringen.
            continue
        id = file.translate(None, '.')
        output += '$("#m3u_list").append("<a href=\\"#\\" id=\\"m3u_file_'+id+'\\" class=\\"list-group-item\\">'+file+'</a>");\n' #Playlist-Datei zu HTML hinzugefügt
        output += '$("#m3u_file_'+id+'").click(function(){ $().loadm3u("'+SERVER_PLAYLIST_ADDR+'/'+file+'", "'+SERVER_MUSIC_ADDR+'"'+local_music_dir+'); });\n' #Klicken Sie auf Auslöser, um die m3u-Datei an das Plug-In zu übergeben
        if flg:
            output += '$().loadm3u("'+SERVER_PLAYLIST_ADDR+'/'+file+'", "'+SERVER_MUSIC_ADDR+'"'+local_music_dir+');\n' #Laden Sie automatisch die erste Wiedergabeliste
            flg = False
    output += '\n});'

    response.content_type = 'text/javascript' #Setzen Sie den MIME-Typ auf JS
    return output

Ist es nur ich, dass der Code sofort verschleiert wird, wenn die # string-Operation implementiert wird?

Umgang mit statischen Dateien

Laden Sie abschließend die Musikdatei und die Wiedergabeliste auf den Server hoch und der Player ist fertig. Anforderungen für diese statischen Dateien können von Bottle wie unten gezeigt akzeptiert werden. Es ist jedoch stabiler, wenn sie von Apache ordnungsgemäß akzeptiert werden, was später beschrieben wird.

au.py


from bottle import route, static_file

@route('/css/<filename>')
def css(filename):
    return static_file(filename, root=ROOT_PATH+'/css')

@route('/js/<filename>')
def js(filename):
    return static_file(filename, root=ROOT_PATH+'/js')

@route('/audio/<filepath:path>')
def audio(filepath):
    return static_file(filepath, root=ROOT_PATH+'/audio')

@route('/playlist/<filename>')
def playlist(filename):
    return static_file(filename, root=ROOT_PATH+'/playlist'

Grundlegende Authentifizierung

Es ist urheberrechtlich geschützt, Musikdateien für jedermann zugänglich zu machen. Legen Sie daher ein Kennwort fest. Die Standardauthentifizierung kann auch auf die Flasche angewendet werden. Dieses Mal erhalten wir die Authentifizierungsinformationen von `` `.htpasswd```, der Kennwortdatei für die Standardauthentifizierung von Apache. Wenn Sie jedoch die Standardauthentifizierung von Apache aktivieren, funktioniert sie nicht ordnungsgemäß. Deaktivieren Sie daher unbedingt eine der beiden Authentifizierungen.

au.py


from bottle import route, auth_basic
from crypt import crypt

def check(user, passwd): #Erstellen Sie Ihre eigene Passwortprüfungsfunktion(Mit anderen Worten kann es sich auch um eine Siebauthentifizierung handeln)
    for line in open(ROOT_PATH+'/.htpasswd', 'r'): #.Holen Sie sich Zeile für Zeile von htpasswd
        htpasswd = line[:-1].split(':') #Separater Benutzername und verschlüsseltes Passwort
        if user is not None and htpasswd[1] is None: #.Aktivieren Sie die Authentifizierung, auch wenn nur der Benutzername festgelegt ist
            if user == htpasswd[0]:
                return True
        elif user is not None and passwd is not None:
            if user == htpasswd[0] and crypt(passwd, htpasswd[1][0:2]) == htpasswd[1]: #Passen Sie den Benutzernamen und das verschlüsselte Passwort an
                return True
    return False

@route('/')
@auth_basic(check) #Zur Authentifizierungsanforderung hinzufügen
def index():
    return template('player.html')

Führen Sie von Apache + WSGI aus

Die Serverfunktion von Bottle ist nicht stabil, daher ist es besser, sie auf die Entwicklung zu beschränken. Dieses Mal werde ich ein Beispiel für das Aufrufen von Apache vorstellen, das jedoch stark von der Umgebung abhängt. Verwenden Sie es daher als Referenz. Erstellen Sie zunächst einen Adapter in der WSGI-Datei, der von Apache aufgerufen und an Bottle übergeben wird.

adapter.wsgi


import sys, os
sys.path.append(os.path.dirname(os.path.abspath(__file__))) #Übergeben Sie den Pfad des Ordners, in dem sich das Skript befindet
import bottle, au #Laden Sie die Flasche selbst und die App
application = bottle.default_app()

Schreiben Sie als Nächstes je nach Umgebung Folgendes in eine geeignete Datei, z. B. "httpd.conf" oder "wsgi.conf" von Apache oder eine andere Einstellungsdatei für den virtuellen Host.

httpd.conf


WSGIScriptAlias /aupy /home/example/aupy/adapter.wsgi #Geben Sie den Adapter an
<Directory "/home/example/aupy/">
   Options ExecCGI Indexes FollowSymlinks
   AllowOverride All #.Aktivieren Sie htaccess
   Order deny,allow
   Allow from all
</Directory>

Alias /aupy/audio /home/example/aupy/audio
<Directory "/home/example/aupy/audio">
   AllowOverride All
   Order deny,allow
   Allow from all
</Directory>

Alias /aupy/playlist /home/example/aupy/playlist
<Directory "/home/example/aupy/playlist">
   AllowOverride All
   Order deny,allow
   Allow from all
</Directory>

Wenn Sie die Standardauthentifizierung auf den Musikordner anwenden, wird die Wiedergabe unter Android Chrome anscheinend nicht ordnungsgemäß gestartet. Als Gegenmaßnahme für den direkten Zugriff habe ich Einschränkungen durch Verweise oder Benutzeragenten (Angabe eines bestimmten Modells) vorgenommen.

.htaccess


SetEnvIf Referer "^http://example.com.*" allowReferer #Ermöglichen Sie den Zugriff vom Cloud Music Player
SetEnvIf User-Agent "example" allowReferer #Für bestimmte UAs zulässig
order deny,allow
deny from all
allow from env=allowReferer

Unterstützt japanische Dateinamen

Ich habe vergessen, das Wichtige zu schreiben. Da ich eine HM-Küche für westliche Musik bin, gibt es kein Problem, aber ich denke, die breite Öffentlichkeit wird Musik mit japanischen Dateinamen spielen wollen. Leider wusste ich nicht, wie man Multibyte-URLs in Bottle weiterleitet. Bitte lassen Sie mich wissen, wenn Sie können. Apache kann Multi-Byte-URLs verarbeiten, indem mod_encoding eingeführt wird.

Einführung in die in CentOS 6.2 ausgeführten Befehle. Bitte beachten Sie, dass der Pfad usw. je nach Verteilung unterschiedlich ist. Laden Sie zunächst die erforderlichen Dateien von der Konsole herunter.

wget http://webdav.todo.gr.jp/download/mod_encoding-20021209.tar.gz
wget http://iij.dl.sourceforge.jp/webdav/13905/mod_encoding.c.apache2.20040616
wget http://www.aconus.com/~oyaji/faq/mod_encoding.c-apache2.2-20060520.patch

Extrahieren Sie die heruntergeladene Datei und wenden Sie den Patch an.

tar zxvf mod_encoding-20021209.tar.gz
cd mod_encoding-20021209/
./configure --with-apxs=/usr/sbin/apxs
cp ../mod_encoding.c.apache2.20040616 mod_encoding.c
patch -p0 < ../mod_encoding.c-apache2.2-20060520.patch

Installieren Sie die enthaltene Bibliothek iconv_hook.

cd lib
./configure
make
sudo make install
sudo vi /etc/ld.so.conf
/usr/local/Fügen Sie lib hinzu
ldconfig

Installieren Sie abschließend mod_encoding.

cd ../
make
gcc -shared -o mod_encoding.so mod_encoding.o -Wc,-Wall -L/usr/local/lib -Llib -liconv_hook
sudo make install

Fügen Sie der Apache-Konfigurationsdatei Folgendes hinzu.

httpd.conf


<IfModule mod_encoding.c>
EncodingEngine On
SetServerEncoding UTF-8
DefaultClientEncoding UTF-8 CP932 EUCJP-MS

AddClientEncoding "RMA/*" CP932
AddClientEncoding "xdwin9x/" CP932
AddClientEncoding "cadaver/" UTF-8 EUCJP-MS
AddClientEncoding "Mozilla/" EUCJP-MS
</IfModule>

Starten Sie Apache schließlich mit `` `sudo service httpd restart``` neu und Sie sollten in der Lage sein, korrekt auf die URL zuzugreifen, die Multibytes enthält.

abschließend

Wie war die Einführung von Bottle? Selbst wenn Sie ein Geek sind, versuchen Sie auf jeden Fall, einen Cloud-Musik-Player für Ihre Familie zu entwickeln!

Recommended Posts

Erstelle deinen eigenen Musik-Player mit Bottle0.13 + jPlayer2.5!
Versuchen Sie, Ihr eigenes AWS-SDK mit bash zu erstellen
Erstellen Sie schnell Ihr eigenes Modul mit setuptools (Python)
[Python] Erstelle deinen eigenen LINE-Bot
Machen Sie Ihr eigenes Handbuch. [Linux] [Mann]
Löse dein eigenes Labyrinth mit Q-Lernen
Trainiere UGATIT mit deinem eigenen Datensatz
Erstellen Sie Ihre eigene VPC mit einem einzigen öffentlichen Subnetz Nur mit boto
So erstellen Sie Ihre eigene Domain-Site mit Heroku (kostenloser Plan)
Erstellen Sie einen Videoplayer mit PySimpleGUI + OpenCV
[Stärkung des Lernens] DQN mit Ihrer eigenen Bibliothek
Erstellen Sie mit Twisted Ihren eigenen DNS-Server
Erstellen Sie mit SQLAlchemy Ihren eigenen zusammengesetzten Wert
Machen Sie Ihren eigenen PC für tiefes Lernen
So importieren Sie Ihr eigenes Modul mit jupyter
Veröffentlichen Sie Ihre eigene Python-Bibliothek auf Homebrew
Machen Sie Ihre Fotos mit dem Pillow's Mode Filter bildlich
Schritte zum Installieren Ihrer eigenen Bibliothek mit pip
Ablauf beim Erstellen eines eigenen Pakets mit setup.py mit Python
Memo zum Erstellen einer eigenen Box mit Peppers Python
Rufen Sie mit Go mit cgo Ihre eigene C-Sprachbibliothek auf
Schreiben Sie Ihre eigene Aktivierungsfunktion mit Pytorch (hartes Sigmoid)
Rufen wir Ihre eigene C ++ - Bibliothek mit Python auf (Einstellungen)
[# 2] Mach Minecraft mit Python. ~ Modellzeichnung und Player-Implementierung ~
Definieren Sie Ihre eigene Distanzfunktion mit k-Mitteln des Scikit-Lernens
Machen Sie Jupyter Notebook zu Ihrem eigenen: Ändern Sie Hintergrund und Symbole