Join the Community
and take part in the story

OpenIO SDS python tornado frontend


#1

Hi there,

I’ve made a little python script using tornado and OpenIO SDS python SDK to stream objects over HTTP.
You can find it on github: https://github.com/Mixton/oio-frontend

This is just a demo to show how to use the python sdk.

In fact I wanted to use OpenIO SDS to store HLS videos and stream them using a player like https://flowplayer.org/ so I needed something like this:

Here is how I did it:

1st you need to install an OpenIO SDS cluster: http://docs.openio.io/ (you can use the docker image if you prefer)

Once your cluster is ready you need a video to transcode. You can find very nice videos here: https://cloud.blender.org

To transcode it I use ffmpeg.
e.g:

ffmpeg -v verbose -i myvideo.mp4
-vn -acodec libfaac -map 0:a:0 -ab 128k -ar 48000
-flags -global_header
-hls_time 4 -hls_list_size 0
-hls_segment_filename /tmp/ffmpeg/myvideo.mp4/audio_128000/segment%05d.ts /tmp/ffmpeg/myvideo.mp4/audio_128000/audio_128000.m3u8
-vcodec libx264 -acodec libfaac
-profile:v baseline -b:v 4928k -maxrate 4928k -bufsize 4928k -vf “scale=1280:trunc(ow/a/2)*2” -map 0:0
-pix_fmt yuv420p -flags -global_header
-hls_time 4 -hls_list_size 0
-hls_segment_filename /tmp/ffmpeg/myvideo.mp4/video_4928/segment%05d.ts /tmp/ffmpeg/myvideo.mp4/video_4928/index_4928.m3u8
-vcodec libx264 -acodec libfaac
-profile:v baseline -b:v 1728k -maxrate 1728k -bufsize 1728k -vf “scale=640:trunc(ow/a/2)*2” -map 0:0
-pix_fmt yuv420p -flags -global_header
-hls_time 4 -hls_list_size 0
-hls_segment_filename /tmp/ffmpeg/myvideo.mp4/video_1500/segment%05d.ts /tmp/ffmpeg/myvideo.mp4/video_1500/index_1500.m3u8
-vcodec libx264 -acodec libfaac
-profile:v baseline -b:v 928k -maxrate 928k -bufsize 928k -vf “scale=426:trunc(ow/a/2)*2” -map 0:0
-pix_fmt yuv420p -flags -global_header
-hls_time 4 -hls_list_size 0
-hls_segment_filename /tmp/ffmpeg/myvideo.mp4/video_928/segment%05d.ts /tmp/ffmpeg/myvideo.mp4/video_928/index_928.m3u8
-filter:v scale=-1:160 -r 1 /tmp/ffmpeg/myvideo.mp4/thumbnails/thumb%d.jpg

Now you need a new playlist file to link all the playlists that ffmpeg generated, lets call it index.m3u8:

#EXTM3U
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio-1",NAME="Audio",LANGUAGE="en",AUTOSELECT=YES,URI="audio_128000/audio_128000.m3u8"
#EXT-X-STREAM-INF:BANDWIDTH=4928000,CODECS="avc1.64000d,mp4a.40.2",RESOLUTION=1280x544,AUDIO="audio-1"
video_4928/index_4928.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1500000,CODECS="avc1.64000d,mp4a.40.2",RESOLUTION=640x272,AUDIO="audio-1"
video_1500/index_1500.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=928000,CODECS="avc1.64000d,mp4a.40.2",RESOLUTION=426x180,AUDIO="audio-1"
video_928/index_928.m3u8 

In /tmp/ffmpeg/myvideo.mp4/ you should have something like this:
-rw-r–r-- 1 root root 517 4 mai 08:42 index.m3u8
drwxr-xr-x 2 root root 20480 4 mai 09:29 thumbnails
drwxr-xr-x 2 root root 8192 6 mai 10:18 audio_128000
drwxr-xr-x 2 root root 8192 6 mai 10:18 video_928
drwxr-xr-x 2 root root 8192 6 mai 10:18 video_4928
drwxr-xr-x 2 root root 8192 6 mai 10:18 video_1500

Now you need to upload all these files to OpenIO SDS. I’ve made a small script called oio-cp.py to do that: https://github.com/Mixton/oio-tools (as this script tries to extract exif tags from picture you will need PIL and some other libs)

Run it like that (put your own OIO_SDS_PROXY_IP):
python oio-cp.py -d /tmp/ffmpeg/ --ns OPENIO --account "YOUR_ACCOUNT" --container videos --proxy OIO_SDS_PROXY_IP -v

Now all your files are stored into OpenIO SDS in an account named “YOUR_ACCOUNT” and a container “videos”.

You can run the frontend (https://github.com/Mixton/oio-frontend) to have access to your files through your web browser:
python oio-front.py -n OPENIO -a YOUR_ACCOUNT -u OIO_SDS_PROXY_IP:6006

To access your files you can simply use your web browser and go to http://[oio-front-server-ip]:8282/videos/myvideo.mp4/index.m3u8 for instance.

Finally you can plug your favorite player, here I use flowplayer.
Create your own html file (use httpd or nginx to serve it)
e.g. (do not forget to change the IP address!!)
<!doctype html>


    <title>OpenIO Streamer</title>
    
    <!-- 1. skin -->
    <link rel="stylesheet" href="http://releases.flowplayer.org/7.0.4/skin/skin.css">
    <link rel="stylesheet" href="http://flowplayer.org/media/css/demos/plugins/hlsjs.css">
    <!-- <link rel="stylesheet" href="//flowplayer.org/media/css/demos/plugins/dashjs.css"> -->


    <!-- 2. jquery library - required for video tag based installs -->
    <script src="http://code.jquery.com/jquery-1.12.4.min.js"></script>

    <!-- 3. flowplayer -->
    <script src="http://releases.flowplayer.org/7.0.4/flowplayer.min.js"></script>
    <script src="http://releases.flowplayer.org/hlsjs/flowplayer.hlsjs.min.js"></script>
    <!-- <script src="//releases.flowplayer.org/dashjs/flowplayer.dashjs.min.js"></script> -->
    <script src="http://releases.flowplayer.org/thumbnails/flowplayer.thumbnails.min.js"></script>
<script>
// run script after document is ready
$(function () {

   // install flowplayer into all elements with CSS class="player"
   $(".player").flowplayer();

});
</script>
</head>
<body ng-app='oioBrowser' ng-controller='browserController' >
<div id="fp-hlsjs" class="is-closeable" style="background-color:#777; background-image:url(http://oio-front-server-ip:8282/videos/myvideo.mp4/thumbnails/thumb11.jpg);"></div>

<script>
flowplayer("#fp-hlsjs", {
    splash: false,
    ratio: 9/16,
    debug: true,

    clip: {
        title: "...", // updated on ready
        thumbnails: {          
          template: "http://oio-front-server-ip:8282/videos/myvideo.mp4/thumbnails/thumb{time}.jpg",
          preload: true
        },        
        sources: [            
            { type: "application/x-mpegurl",              
              src:  "http://oio-front-server-ip:8282/videos/myvideo.mp4/index.m3u8" }
        ]
    },
    embed: false

}).on("ready", function (e, api, video) {
    document.querySelector("#fp-hlsjs .fp-title").innerHTML =
            api.engine.engineName + " engine playing " + video.type;

});
</script>
</body>
</html>

Now if you access to this file through your webserver using your web browser you will see that the JS player retrieves the video files using the oio-front web server we started earlier.

See you around.

Maxime