Le framework léger Bottle semble être populaire, donc je vais créer un lecteur de musique cloud pour la pratique. Le produit fini est répertorié dans Bitbucket, donc seuls les principaux points seront expliqués. L'exemple d'opération est disponible sur ici. Au fait, j'ai confirmé l'opération avec Python 2.6.
Il est pratique de pouvoir télécharger et lire à partir de n'importe quel appareil une fois que vous l'achetez, comme iTunes ou Amazon Cloud Player. Cependant, en tant que cuisine d'achat de CD, je souhaite toujours le lire avec le fichier source sonore à portée de main. Google Music vous permet de télécharger des fichiers vous-même, mais l'industrie de la musique japonaise est inflexible Par conséquent, il sera difficile d'exploiter un service similaire au Japon pour le moment. Par conséquent, j'ai toujours voulu créer mon propre lecteur de musique dans le cloud, je vais donc profiter de l'occasion pour le mettre en œuvre.
Une autre option consiste à créer un serveur de streaming en utilisant Subsonic ou Icecast. Bien que cela soit facile et que de nombreux joueurs puissent y jouer, cela présente l'inconvénient de subir une charge de traitement car la source sonore est encodée côté serveur. (En fait, j'avais l'habitude d'utiliser cette méthode jusqu'à présent, mais il y a un problème avec l'opération de sélection de morceau.) Cette fois, la plupart de la lecture sera laissée au plug-in jQuery jPlayer, un lecteur multimédia basé sur HTML5. Je ne sais pas si le framework léger Bottle entre en jeu car la partie traitement de Python émoussé consiste simplement à lister la liste de lecture, mais je pense que c'est juste pour étudier.
Bottle vous permet de créer des applications Web avec une syntaxe très simple.
au.py
# -*- coding: utf-8 -*-
from bottle import route, run #Il semble courant de ne récupérer que les méthodes nécessaires (?)
@route('/hello') #Spécifiez le chemin cible pour exécuter la fonction suivante
def hello(): #Le nom de la fonction peut être n'importe quoi
return 'Hello World!' #Contenu à afficher dans le navigateur
if __name__ == "__main__": #Notez que si vous ne le bloquez pas, une erreur se produira lorsque vous l'exécuterez à partir d'Apache décrit plus loin.
run(host='0.0.0.0', port=8080, debug=True, reloader=True)
Pour l'argument de run ()
Exécutez le script ci-dessus à partir de la ligne de commande.
python au.py
Si vous accédez à l'adresse du serveur http: //: 8080 / hello depuis votre navigateur, vous devriez voir "Hello World!".
Maintenant, implémentons le lecteur de musique cloud souhaité à partir d'ici. Le moteur de template de Bottle peut être utilisé comme Django, donc les utilisateurs expérimentés de Django devraient être heureux de l'utiliser facilement. Les spécifications détaillées peuvent être trouvées dans le Document original.
au.py
from bottle import route, template, TEMPLATE_PATH
import os
ROOT_PATH = os.path.dirname(os.path.abspath(__file__)) #Chemin absolu vers le dossier où se trouve ce script
TEMPLATE_PATH.insert(0, ROOT_PATH+'/templates') #Spécifiez le dossier pour stocker le fichier de modèle
@route('/')
def index():
return template('player.html') #Vous pouvez également passer des paramètres à la suite du fichier modèle
Dans le modèle, nous préparerons immédiatement jPlayer. Puisque l'apparence est secondaire, CSS utilise [Blue Monday] qui vient avec jPlayer, et la partie HTML est un lecteur vocal avec une liste de lecture de ce site. J'étais autorisé à me référer!
De plus, les parties communes de chaque modèle sont rassemblées dans un fichier modèle séparé avec
% rebase () '' ''. Notez que cela a un format différent de Django. Veuillez noter que les `` jplayer.m3u.js``` et
`ʻinit.js``` passés dans les paramètres sont des scripts que vous créerez plus tard.
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']) <!--Étant donné que les paramètres peuvent être passés après le fichier modèle, spécifiez les fichiers CSS et JS à lire en plus.-->
<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>
Ensuite, écrivez le fichier modèle pour la partie commune.
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: <!--Lire le fichier CSS passé en paramètre-->
<link rel="stylesheet" type="text/css" href="css/{{item}}">
% end
% for item in js: <!--Lire le fichier JS également passé en paramètre-->
<script type="text/javascript" src="js/{{item}}"></script>
% end
</head>
<body>
{{!base}} <!--Voici le contenu du fichier modèle appelant-->
</body>
</html>
À ce stade, je ne peux pas encore exécuter jPlayer.
Implémentez un plug-in qui définira le fichier m3u / m3u8 sur la liste de lecture jPlayer. Il peut être implémenté en tant que plug-in jQuery en l'écrivant dans le format ci-dessous.
;(function($) {
$.fn.loadm3u = function (){
//Traitement du contenu
}
})(jQuery);
Cette fois, nous allons créer un plug-in qui suppose l'utilisation suivante.
$().loadm3u(chemin du fichier m3u,Chemin du dossier de musique côté serveur,Chemin à remplacer(option))
Le plug-in a une fonction pour remplacer automatiquement le chemin spécifié à l'avance. En conséquence, les fichiers m3u / m3u8 crachés par foobar2000 etc. peuvent être utilisés tels quels dans le lecteur de musique cloud.
#### **`js/jplayer.m3u.js`**
;(function($) { $.fn.loadm3u = function (filepath, server_music_dir, local_music_dir){ $.get(filepath, function(data){ //Obtenez le fichier m3u passé en argument var data_array = data.split(/\r\n|\r|\n/); //Split à la pause var playlists = []; for (var i = 0; i < data_array.length; i++){ //Traiter ligne par ligne if(data_array[i] != ""){ if (typeof local_music_dir != "undefined") { data_array[i] = data_array[i].replace(local_music_dir+"\", "") //Supprimer le chemin à remplacer } unix_dir_path = data_array[i].replace(/\/g, "/") //Corriger la barre oblique inverse en barre oblique title = unix_dir_path.split("/"); //Fractionner avec barre oblique playlists.push({"title":title[title.length-1], "free":true, "mp3":server_music_dir+"/"+unix_dir_path}); //Stockez le nom de fichier et le chemin du fichier de la source sonore dans la liste } }
$("#jquery_jplayer_N").jPlayer("destroy"); //Initialiser jPlayer
var Playlist = new jPlayerPlaylist( //Listes de lecture et options à charger dans jPlayer
{
jPlayer: "#jquery_jplayer_N",
cssSelectorAncestor: "#jp_container_N"
}, playlists, {
supplied: "mp3" //Formats de fichiers audio pris en charge
}
);
});
}
})(jQuery);
De plus, bien que seul le mp3 soit spécifié dans le script ci-dessus, il semble qu'il sera lu sans problème même si vous passez un fichier de musique tel que ogg juste pour le chemin du fichier. flac n'a pas fonctionné car le navigateur ne prend pas en charge la lecture.
## Générer un fichier JS pour l'initialisation en Python
Tout d'abord, préparez un script pour décrire les paramètres ensemble.
#### **`setting.py`**
```py
#! -*- coding: utf-8 -*-
import os
SERVER_MUSIC_ADDR = os.path.expandvars('audio') #Par rapport aux dossiers de musique/URL absolue
SERVER_PLAYLIST_ADDR = os.path.expandvars('playlist') #Par rapport aux dossiers de playlist/URL absolue
SERVER_PLAYLIST_DIR = os.path.expandvars('/home/example/aupy/playlist') #Chemin absolu du dossier de la playlist
LOCAL_MUSIC_DIR = os.path.expandvars('C:\Users\example\Music') #Chemin absolu du dossier de musique local à remplacer
Ensuite, listez les fichiers dans le dossier playlist sur le serveur, ajoutez-les à
au.py
from bottle import route, response
from setting import * #Lisez le fichier de paramètres
@route('/js/init.js') #Détourner une demande pour ce fichier JS
def initjs():
if LOCAL_MUSIC_DIR:
local_music_dir = ', "'+LOCAL_MUSIC_DIR.replace('\\', '\\\\')+'"' #Définissez le chemin à remplacer
else:
local_music_dir = ''
output = '$(function(){\n' #Commencer à écrire le contenu de sortie
files = os.listdir(SERVER_PLAYLIST_DIR) #Lister les fichiers dans le dossier de la playlist
files.sort()
flg = True
for file in files:
if file.startswith('.'): #.Pour sauter htaccess, etc.
continue
id = file.translate(None, '.')
output += '$("#m3u_list").append("<a href=\\"#\\" id=\\"m3u_file_'+id+'\\" class=\\"list-group-item\\">'+file+'</a>");\n' #Fichier de liste de lecture ajouté au HTML
output += '$("#m3u_file_'+id+'").click(function(){ $().loadm3u("'+SERVER_PLAYLIST_ADDR+'/'+file+'", "'+SERVER_MUSIC_ADDR+'"'+local_music_dir+'); });\n' #Cliquez sur le déclencheur pour transmettre le fichier m3u au plug-in
if flg:
output += '$().loadm3u("'+SERVER_PLAYLIST_ADDR+'/'+file+'", "'+SERVER_MUSIC_ADDR+'"'+local_music_dir+');\n' #Charger automatiquement la première playlist
flg = False
output += '\n});'
response.content_type = 'text/javascript' #Définir le type MIME sur JS
return output
Est-ce seulement moi que le code devient obscurci à la fois lorsque l'opération #string est implémentée?
Enfin, téléchargez le fichier musical et la liste de lecture sur le serveur et le lecteur est terminé. Les demandes pour ces fichiers statiques peuvent être acceptées par Bottle comme indiqué ci-dessous, mais il est plus stable s'ils sont correctement acceptés par Apache, ce qui sera décrit plus loin.
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'
Il est respectueux des droits d'auteur de rendre les fichiers musicaux accessibles à tous, alors définissez un mot de passe. L'authentification de base peut également être appliquée à Bottle. Cette fois, nous obtiendrons les informations d'authentification de
.htpasswd``` qui est le fichier de mot de passe pour l'authentification de base d'Apache. Cependant, si vous activez à la fois l'authentification de base d'Apache, cela ne fonctionnera pas correctement, alors assurez-vous de désactiver l'un ou l'autre.
au.py
from bottle import route, auth_basic
from crypt import crypt
def check(user, passwd): #Créez votre propre fonction de vérification de mot de passe(En d'autres termes, il peut également s'agir d'une authentification de passoire)
for line in open(ROOT_PATH+'/.htpasswd', 'r'): #.Obtenir ligne par ligne de htpasswd
htpasswd = line[:-1].split(':') #Nom d'utilisateur et mot de passe cryptés séparés
if user is not None and htpasswd[1] is None: #.Activer l'authentification même si seul le nom d'utilisateur est défini
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]: #Faites correspondre le nom d'utilisateur et le mot de passe crypté
return True
return False
@route('/')
@auth_basic(check) #Ajouter à la demande d'authentification
def index():
return template('player.html')
La fonction serveur de Bottle n'est pas stable, il est donc préférable de la limiter au développement. Cette fois, je vais vous présenter un exemple d'appel depuis Apache, mais cela dépend grandement de l'environnement, alors veuillez l'utiliser comme référence. Tout d'abord, créez un adaptateur dans le fichier WSGI qui sera appelé à partir d'Apache et transmis à Bottle.
adapter.wsgi
import sys, os
sys.path.append(os.path.dirname(os.path.abspath(__file__))) #Passez le chemin du dossier où se trouve le script
import bottle, au #Chargez la bouteille elle-même et l'application
application = bottle.default_app()
Ensuite, écrivez ce qui suit dans un fichier approprié en fonction de l'environnement, tel que httpd.conf '' ou
wsgi.conf '' d'Apache, ou un autre fichier de configuration d'hôte virtuel.
httpd.conf
WSGIScriptAlias /aupy /home/example/aupy/adapter.wsgi #Spécifiez l'adaptateur
<Directory "/home/example/aupy/">
Options ExecCGI Indexes FollowSymlinks
AllowOverride All #.Activer 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>
De plus, si vous appliquez l'authentification de base au dossier de musique, il semble que la lecture ne démarre pas correctement sur Android Chrome, donc comme contre-mesure pour un accès direct, j'ai compromis avec les restrictions par les référents ou les agents utilisateurs (en spécifiant un modèle spécifique).
.htaccess
SetEnvIf Referer "^http://example.com.*" allowReferer #Autoriser l'accès à partir du lecteur de musique cloud
SetEnvIf User-Agent "example" allowReferer #Autorisé pour certains UA
order deny,allow
deny from all
allow from env=allowReferer
J'ai oublié d'écrire la chose importante. Puisque je suis une cuisine HM de musique occidentale, il n'y a pas de problème, mais je pense que le grand public voudra jouer de la musique avec des noms de fichiers japonais. Malheureusement, je ne savais pas comment acheminer des URL multi-octets dans Bottle, alors faites-le moi savoir si vous le pouvez. Apache peut gérer les URL multi-octets en introduisant mod_encoding.
Présentation des commandes exécutées dans CentOS 6.2. Veuillez noter que le chemin, etc. diffère selon la distribution. Tout d'abord, téléchargez les fichiers requis à partir de la console.
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
Extrayez le fichier téléchargé et appliquez le correctif.
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
Installez la bibliothèque iconv_hook incluse.
cd lib
./configure
make
sudo make install
sudo vi /etc/ld.so.conf
/usr/local/Ajouter une bibliothèque
ldconfig
Enfin, installez 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
Ajoutez ce qui suit au fichier de configuration Apache.
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>
Enfin, redémarrez Apache avec
sudo service httpd restart '' et vous devriez pouvoir accéder correctement à l'URL contenant des multi-octets.
Comment s'est passée l'introduction de Bottle? Bien sûr, même si vous êtes un geek, essayez de créer un lecteur de musique cloud pour votre famille!
Recommended Posts