如何通过内置的python http服务器提供mp3文件

|| 我目前正在尝试使用Python提供MP3文件。问题是我只能播放一次MP3。之后,媒体控件停止响应,因此我需要重新加载整个页面才能再次收听MP3。 (在Chrome中测试) 问题:运行以下脚本,并在浏览器中输入http://127.0.0.1/test.mp3,将会返回MP3文件,只有刷新页面后才能播放该文件 笔记: 将页面另存为HTML并直接通过Chrome加载(没有Python服务器)会使问题消失。 用Apache提供文件可以解决该问题,但是这过于矫kill过正:我想使脚本非常易于使用,并且不需要安装Apache。 这是我使用的代码:
import string
import os
import urllib
import socket

# Setup web server import string,cgi,time
import string,cgi,time
from os import curdir, sep
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
import hashlib

class MyHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        try:
            # serve mp3 files
            if self.path.endswith(\".mp3\"):
                print curdir + sep + self.path
                f = open(curdir + sep + self.path, \'rb\')
                st = os.fstat( f.fileno() )
                length = st.st_size
                data = f.read()
                md5 = hashlib.md5()
                md5.update(data)
                md5_key = self.headers.getheader(\'If-None-Match\')
                if md5_key:
                  if md5_key[1:-1] == md5.hexdigest():
                    self.send_response(304)
                    self.send_header(\'ETag\', \'\"{0}\"\'.format(md5.hexdigest()))
                    self.send_header(\'Keep-Alive\', \'timeout=5, max=100\')
                    self.end_headers()
                    return

                self.send_response(200)
                self.send_header(\'Content-type\',    \'audio/mpeg\')
                self.send_header(\'Content-Length\', length )
                self.send_header(\'ETag\', \'\"{0}\"\'.format(md5.hexdigest()))
                self.send_header(\'Accept-Ranges\', \'bytes\')
                self.send_header(\'Last-Modified\', time.strftime(\"%a %d %b %Y %H:%M:%S GMT\",time.localtime(os.path.getmtime(\'test.mp3\'))))
                self.end_headers()
                self.wfile.write(data)
                f.close()
            return
        except IOError:
           self.send_error(404,\'File Not Found: %s\' % self.path)

from SocketServer import ThreadingMixIn
class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
    pass

if __name__ == \"__main__\":
    try:
       server = ThreadedHTTPServer((\'\', 80), MyHandler)
       print \'started httpserver...\'
       server.serve_forever()
    except KeyboardInterrupt:
       print \'^C received, shutting down server\'
       server.socket.close()
    
已邀请:
BaseServer
是单线程的,应使用
ForkingMixIn
ThreadingMixIn
支持多个连接。 例如替换行:
server = HTTPServer((\'\', 80), MyHandler)
from SocketServer import ThreadingMixIn

class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
    pass

server = ThreadedHTTPServer((\'\', 80), MyHandler)
    
编辑:在意识到Mapadd仅计划在实验室中使用它之前,我写了很多这样的内容。他的用例可能不需要WSGI。 如果您愿意将其作为wsgi应用程序运行(出于任何实际可扩展性的考虑,我建议通过vanilla CGI进行运行),则可以使用下面包含的脚本。 我自由地修改了您的源代码……这与上面的假设一致。.顺便说一句,您应该花一些时间检查您的html是否合理合规...这将有助于确保您获得更好的跨浏览器兼容性。 。原始文件没有
<head>
<body>
标签...我的(下面)严格是html原型,可以进行改进。 要运行此程序,您只需在shell中运行python可执行文件,然后在8080上浏览到该计算机的ipaddress。如果您是在生产网站上进行此操作,则应该使用lighttpd或apache来提供文件,但是因为这很简单对于实验室使用,嵌入式wsgi参考服务器应该可以。如果要在apache或lighttpd中运行,请替换文件底部的“ 8”行。 另存为mp3.py
from webob import Request
import re
import os
import sys

####
#### Run with:
#### twistd -n web --port 8080 --wsgi mp3.mp3_app

_MP3DIV = \"\"\"<div id=\"musicHere\"></div>\"\"\"

_MP3EMBED = \"\"\"<embed src=\"mp3/\" loop=\"true\" autoplay=\"false\" width=\"145\" height=\"60\"></embed>\"\"\"

_HTML = \'\'\'<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\"><html><head></head><body> Hello %s %s</body></html> \'\'\' % (_MP3DIV, _MP3EMBED)

def mp3_html(environ, start_response):
    \"\"\"This function will be mounted on \"/\" and refer the browser to the mp3 serving URL.\"\"\"

    start_response(\'200 OK\', [(\'Content-Type\', \'text/html\')])
    return [_HTML]

def mp3_serve(environ, start_response):
    \"\"\"Serve the MP3, one chunk at a time with a generator\"\"\"
    file_path = \"/file/path/to/test.mp3\"
    mimetype = \"application/x-mplayer2\"
    size = os.path.getsize(file_path)
    headers = [
        (\"Content-type\", mimetype),
        (\"Content-length\", str(size)),
    ]
    start_response(\"200 OK\", headers)
    return send_file(file_path, size)

def send_file(file_path, size):
    BLOCK_SIZE = 4096
    fh = open(file_path, \'r\')
    while True:
        block = fh.read(BLOCK_SIZE)
        if not block:
            fh.close()
            break
        yield block

def _not_found(environ,start_response):
    \"\"\"Called if no URL matches.\"\"\"
    start_response(\'404 NOT FOUND\', [(\'Content-Type\', \'text/plain\')])
    return [\'Not Found\']

def mp3_app(environ,start_response):
    \"\"\"
    The main WSGI application. Dispatch the current request to
    the functions andd store the regular expression
    captures in the WSGI environment as  `mp3app.url_args` so that
    the functions from above can access the url placeholders.

    If nothing matches call the `not_found` function.
    \"\"\"
    # map urls to functions
    urls = [
        (r\'^$\', mp3_html),
        (r\'mp3/?$\', mp3_serve),
    ]
    path = environ.get(\'PATH_INFO\', \'\').lstrip(\'/\')
    for regex, callback in urls:
        match = re.search(regex, path)
        if match is not None:
            # assign http environment variables...
            environ[\'mp3app.url_args\'] = match.groups()
            return callback(environ, start_response)
    return _not_found(environ, start_response)
从bash shell运行,输入::10ѭ(保存mp3.py的目录)(或仅将mp3.py放在ѭ11的某个位置)。 现在浏览到外部ip(即http://some.ip.local:8080 /),它将直接为mp3提供服务​​。 我尝试运行原始应用程序,因为它被发布了,但无法获取它作为mp3的源代码,它在Linux中出现错误,对我咆哮...     

要回复问题请先登录注册