# -*- coding: UTF-8 -*-
import re
import os
import urllib
from http.server import HTTPServer, SimpleHTTPRequestHandler
class MyHandler(SimpleHTTPRequestHandler):
def do_GET(self):
f, is_ios, start, r_size = self.send_head()
if not f:
return
try:
if is_ios:
self.copyfile2(f, self.wfile, start, r_size)
else:
self.copyfile(f, self.wfile)
finally:
f.close()
def copyfile2(self, source, outputfile, start, length):
source.seek(start)
buf = source.read(length)
if not buf:
print("copy fail")
return
outputfile.write(buf)
def send_head(self):
path = self.translate_path(self.path)
f = None
if os.path.isdir(path):
parts = urllib.parse.urlsplit(self.path)
if not parts.path.endswith('/'):
self.send_response(301)
new_parts = (parts[0], parts[1], parts[2] + '/', parts[3], parts[4])
new_url = urllib.parse.urlunsplit(new_parts)
self.send_header("Location", new_url)
self.end_headers()
return None
for index in "index.html", "index.htm":
index = os.path.join(path, index)
if os.path.exists(index):
path = index
break
else:
return self.list_directory(path), False, 0, 0
ctype = self.guess_type(path)
# 查看是否是ios端
is_ios = False
user_agent = self.headers.get("User-Agent", "None")
if user_agent.find("Mac OS") != -1:
is_ios = True
print("send_head", ctype, is_ios, user_agent)
return_start, return_need_size = 0, 0
try:
f = open(path, 'rb')
except OSError:
self.send_error(404, "File not found")
return None, False, return_start, return_need_size
try:
fs = os.fstat(f.fileno())
size = fs[6]
if not is_ios:
self.send_response(200)
self.send_header("Content-Length", str(size))
self.send_header("Content-type", ctype)
self.send_header("Last-Modified", self.date_time_string(fs.st_mtime))
self.end_headers()
return f, False, return_start, size
if ctype != "video/mp4":
self.send_response(206)
self.send_header("Content-Length", str(size))
return_need_size = size
else:
h_range = self.headers.get("Range", "-1")
matched = re.search("(\d*)-(\d*)", h_range).groups()
if not matched:
return f, False, return_start, return_need_size
return_start, r_end = matched
return_start, r_end = int(return_start), int(r_end)
return_need_size = size
if r_end != 0 and r_end > return_start:
return_need_size = r_end - return_start + 1
self.send_response(206)
self.send_header('Accept-Ranges', 'bytes')
if r_end > 0:
length = r_end - return_start + 1
self.send_header("Content-Length", str(length))
self.send_header('Content-Range', 'bytes {0}-{1}/{2}'.format(return_start, r_end, size))
else:
length = size - return_start
self.send_header("Content-Length", str(length))
self.send_header('Content-Range', 'bytes {0}-{1}/{2}'.format(return_start, size-1, size))
self.send_header("Content-type", ctype)
self.send_header("Last-Modified", self.date_time_string(fs.st_mtime))
self.end_headers()
return f, True, return_start, return_need_size
except Exception as e:
print(e)
f.close()
def start_server(host='', port=9093):
sever = HTTPServer((host,port),MyHandler)
print("server start")
sever.serve_forever()
if __name__ == "__main__":
start_server()
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<video width="320" height="240" controls="controls">
<source src="08.31.mp4" type="video/mp4">
</video>
</body>
</html>