«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

VIDEOCUBE

[ Cube Project ] Python MP4 Streaming Server 본문

프로젝트

[ Cube Project ] Python MP4 Streaming Server

라떼청년 2017. 12. 5. 01:15

Project Name : [Cube]

ㄴ Media Streaming Server


참고 : 

Nginx + Python CGI 연동 준비

Python 서버 구축하기 [CGIHTTPServer]


[MP4] 파일 미디어 샘플과 시간 정보를 구하는 방법

[MP4] 분석 하기 | MPEG-4 파트 14 | MP4Box 설치


Nginx 설치하기




이전에 Nginx  + CGIHTTPServer 서버를 설정했다.


기존에 작성한 hello.py 를 다음과 같이 변경한다.


1. mv hello.py cube.py


2. nginx 설정도 기존 hello.py > cube.py 로 변경한다.


3. nginx 설정


   ㄴ location ~ \.(mp4|json)$ {

        rewrite ^/(.*) /cgi-bin/cube.py?file=$1 break;

        proxy_pass http://127.0.0.1:8000;

    }


4. module 폴더를 만든다

   모듈은 module 하위에 

   ㄴ touch __init__.py

   ㄴ touch mp4.py



* python 작업 시에 vim 설정을 하고 작성하는 것을 추천한다. 

  ㄴ 저는 set tabstop=4 로 설정을 하고 작성합니다.


  참고 : http://pythoninreal.blogspot.kr/2013/12/vim-python.html


.

├── Robotica.mp4

├── cgi-bin

│   ├── cube.py

│   └── module

│       ├── __init__.py

│       ├── __init__.pyc

│       └── mp4.py

└── index.html



[ cube.py Source ]


#!/usr/bin/env python


import cgi, re, json, sys, os

from module.mp4 import MP4


#JSON Print

def _json(data):

print "Content-type: application/json\n\n"

print(json.dumps(data))


#MP4 Stream Out

def _out(filename, chunk_size=1024):

out_file = sys.stdout

head =  "Content-Type:application/octet-stream; name = \"%s\"\r\n" % filename;

print head


fo = open(filename, "rb")

while True:

out = fo.read(chunk_size)

if out:

out_file.write(out)

else:

break;


fo.close()


form = cgi.FieldStorage()

fileName = form.getvalue('file')


p = re.compile("(.+)\.(mp4|json)(.+)?")

g = p.search(fileName)


data = {'error':'none', 'data':None}


if g:

fileName = g.group(1)                         #파일 이름

ext = g.group(2)                  #파일 확장자


fileName = "%s.%s" % (fileName, 'mp4')          #인코딩 완료 된 mp4 파일만 존재 합니다.


if not os.path.exists(fileName):                #파일 존재 여부 체크

data["error"] = "Unknown File"

_json(data)

elif ext == 'json': #미디어 정보 획득

data["error"] = "none"

data["data"] = MP4(fileName).dic()

_json(data)

elif ext == 'mp4':  #Mp4 파일 Stream

_out(fileName)

else:

data["error"] = "Unknown File"                  #Error Message

_json(data)



[ mp4.py Source ]


#!/usr/bin/env python

#coding:utf-8



class MP4(object):

def __init__(self, file_name):

self.fileName = file_name


def dic(self):

return self.fileName




http://media.videocube.lab/Robotica.json > 미디어 정보 획득 ( json )



http://media.videocube.lab/Roboticat.json  > 없는 파일을 호출 하는 경우



http://media.videocube.lab/Robotica.mp4 > mp4 다운로드




mp4 재생





기본 형태를 소스로 구현하였다.


https://github.com/pluto90k/cube


# 분석기

    def _parser(self, name, dic, data):

        if name == 'moov': out = self._moov(data)

        elif name == 'mvhd': out = self._mvhd(data)

        elif name == 'trak': out = self._trak(data)

        elif name == 'mdia': out = self._media(data)

        elif name == 'minf': out = self._minf(data)

        elif name == 'stbl': out = self._stbl(data)

        elif name == 'stts': out = self._stts(data)

        elif name == 'stsd': out = self._stsd(data)

        elif name == 'stco': out = self._stco(data)

        elif name == 'stsz': out = self._stsz(data)

        elif name == 'stsc': out = self._stsc(data)

        elif name == 'mdat': out = {}

        else:out = {'data':self._hex(data)}



  #동일한 Type 이 존재 하는 경우 배열로 변경

        if dic.has_key(name):

            if isinstance(dic[name], dict):dic[name]=[dic[name], out]

            else:dic[name].append(out)

        else:dic[name] = out

        return dic



    def _read(self, bio, dic):

        while True:

            size = bio.read(4)

            if size == '':break

            size = int(size.encode('hex'), 16)

            data = bio.read(size - 4)

            tp = data[:4].decode('utf-8')

            self._parser(tp, dic, data[4:])



다음과 같이 미디어 정보를 가져올 수 있다.

좀 더 상세한 정보를 Json 화 하도록 한다.

다음은 HTML5 기본 플레이어를 구현 하여 페이지에 올려보도록 하겠다.










반응형
Comments