2

Im trying to serve a video file from my home WAMP server (windows 8) to the browser, but the browser keeps giving an error 500, and the apache logs says malformed header from script 's.py': Bad header: G@

"s.py" is my python version 3.4 script

n="\\wamp\\www\\r.mp4"
print ("Last-Modified: Fri, 24 Apr 2015 22:09:52 GMT")
print ("Accept-Ranges: bytes")
print ("Content-Length:", os.path.getsize(n))
print ("Content-type: video/mp4\r\n\r\n")

f=open(n, 'rb')
d=f.read()
sys.stdout.buffer.write(d)
sys.stdout.flush()
f.close()

i can run other simple python scripts on the server using the browser, so i know thats working, but for some reason it wont serve this mp4 file.

in the browser i call it using the URL "localhost/s.py", then it just gives error 500, and server log shows malformed header.

I been working on it all day, anybody have any idea how to solve it,

Thanks

Paul Man
  • 141
  • 1
  • 10
  • What do you intend to do? – Ganesh Jun 19 '17 at 02:41
  • Find root dir of your server & paste your mp4 in there. You can directly access it by `localhost/filename.mp4` – Ganesh Jun 19 '17 at 02:44
  • I can access it directly, but if i use a python script i can control which files are visible from the browser by serving it with the script, but somehow the script dont work – Paul Man Jun 19 '17 at 02:51

2 Answers2

1

Python can be used to serve MP4 to you browser. But you can't throw a Python script to a WAMP server, like it was a PHP script.

If you were set on having a Python web application serve video through your Apache server, you'd have to build a WSGI application and look into mod_wsgi to be able to serve Python apps with Apache. You can also run the WSGI application without Apache.

An oversimplified WSGI application to serve mp4 video from a directory could be:

import os
from flask import Flask, send_file, make_response


APP = Flask(__name__)
MEDIA_PATH = '/path/to/your/media/directory'


@APP.route('/<vid_name>')
def serve_video(vid_name):
    vid_path = os.path.join(MEDIA_PATH, vid_name)
    resp = make_response(send_file(vid_path, 'video/mp4'))
    resp.headers['Content-Disposition'] = 'inline'
    return resp


if __name__ == '__main__':
    APP.run()
  1. Edit MEDIA_PATH with the full path to your the directory holding your videos.

  2. Save this script somewhere as video_server.py (for example).

  3. Run this script python video_server.py

  4. Via your browser, access to localhost:5000/some_video.mp4 (where some_vdeo.mp4 is the name of an existing video)

Note: You can edit APP.run() with the keyword arguments port and/or host:

  • port: to be able to listen on a different port. APP.run(port=8000)
  • host: to listen to requests from outside your computer. APP.run(host='0.0.0.0)

Edit: flask is an external library that needs to be installed. Look on the website for installation instructions. Simple version: pip install flask

Luis Alvarez
  • 674
  • 6
  • 8
  • Wow, awesome comment, thanks a million. Actually i need the browser to access the video files like /localhost/video_server.py?video_id=2 then the python script would look in a database for video 2, and serve that, is that possible? – Paul Man Jun 19 '17 at 03:09
  • Or can i write a php script that runs the python script, and have the python script stream the video? like /localhost/video.php?video_id=2 where video.php would call the python script and it would do the work? – Paul Man Jun 19 '17 at 03:15
  • The reason i need python to work is that im using a special video library that only comes in python – Paul Man Jun 19 '17 at 03:16
  • Could you provide a link to the library? I suggest you fully dump PHP in favor of Python regardless. – Luis Alvarez Jun 19 '17 at 03:17
  • the library is streamlink https://github.com/streamlink/streamlink i try to dump php but the python isnt working as you can see, im wondering if the headers in my python script above are correct? – Paul Man Jun 19 '17 at 03:22
  • Sure, the headers don't look bad. But your script is not the way a Python web application works. Python is not PHP. And I don't think you can dump the binary content of the video to standard output and hope it'll work out. I strongly suggest you look into the idiomatic way of doing this on Python, using Flask. And take the script I included in my answer as a starting point. – Luis Alvarez Jun 19 '17 at 03:27
  • im sending video right now using php by simply reading the file and doing an echo and it plays fine in the browser, so i thought i could do the same in python, but when i try it dont work as you can see, i wanted a simple solution since i dont know python at all – Paul Man Jun 19 '17 at 03:30
  • look at this link, look at the answer with 10 rating, they show how to call python from php and echo the output of python https://stackoverflow.com/questions/166944/calling-python-in-php – Paul Man Jun 19 '17 at 03:36
1

I just ran into the exact same problem (with pdf rather than mp4). Your original code was close. The problem was that sys.stdout.flush needs to be before the sys.stdout.buffer.write to ensure that the headers appear first. The edited code is below, which worked for me.

n="\\wamp\\www\\r.mp4"
print ("Last-Modified: Fri, 24 Apr 2015 22:09:52 GMT")
print ("Accept-Ranges: bytes")
print ("Content-Length:", os.path.getsize(n))
print ("Content-type: video/mp4\r\n\r\n")
sys.stdout.flush()

f=open(n, 'rb')
d=f.read()
sys.stdout.buffer.write(d)
f.close()
user1763510
  • 1,070
  • 1
  • 15
  • 28