zoukankan      html  css  js  c++  java
  • 11.nginx upload module + python django 后台 实现视频上传与切片

    1.需求:支持视频上传并切片,支持通过m3u8文件播放

    2.视频切片的上一节已经谈过,这一节主要是视频上传的处理

    第一步:upload-module模块安装

    -----------首先下载upload-module

    -----------然后使用源码编译安装nginx: .configure --add-module=/path/nginx-upload-module/

    第二步:确认是否已经安装了upload-module,使用指令:/usr/local/nginx/sbin/nginx -V

    第三部:添加配置文件

    http {
        include       mime.types;
        default_type  application/octet-stream;
        client_max_body_size 3000m;
        fastcgi_connect_timeout 300;
        fastcgi_send_timeout 300;
        fastcgi_read_timeout 300;
        fastcgi_buffer_size 256k;
        fastcgi_buffers 2 256k;
        fastcgi_busy_buffers_size 256k;
        fastcgi_temp_file_write_size 256k;
        #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
        #                  '$status $body_bytes_sent "$http_referer" '
        #                  '"$http_user_agent" "$http_x_forwarded_for"';
    
        #access_log  logs/access.log  main;
        
        add_header Access-Control-Allow-Origin "http://weibo.duoyioa.com";
        add_header Access-Control-Allow-Headers X-Requested-With;
        add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
    
        sendfile        on;
        #tcp_nopush     on;
    
        #keepalive_timeout  0;
        keepalive_timeout  300;
        
        #gzip  on;
        
         server {
         client_max_body_size 3000m;
         client_body_buffer_size 400m;
         listen 80;
         listen 443 ssl;
    
        ssl_certificate /usr/local/nginx/ssl/duoyioa.cer;
        ssl_certificate_key /usr/local/nginx/ssl/duoyioa.key;
        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;
        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;
         
         # Upload form should be submitted to this location
        location /upload {
            # Pass altered request body to this location
            upload_pass   @python;
    
            # Store files to this directory
            # The directory is hashed, subdirectories 0 1 2 3 4 5 6 7 8 9 should exist
            upload_store /var 1;
    
            # Allow uploaded files to be read only by user
            upload_store_access user:rw;
    
            # Set specified fields in request body
            upload_set_form_field $upload_field_name.name "$upload_file_name";
            upload_set_form_field $upload_field_name.content_type "$upload_content_type";
            upload_set_form_field $upload_field_name.path "$upload_tmp_path";
    
            # Inform backend about hash and size of a file
            upload_aggregate_form_field "$upload_field_name.md5" "$upload_file_md5";
            upload_aggregate_form_field "$upload_field_name.size" "$upload_file_size";
    
            upload_pass_form_field "^submit$|^description$";
    
            upload_cleanup 400 404 499 500-505;
            upload_limit_rate 0;
            upload_max_file_size    3000m;
            client_max_body_size    3000m;  
        }
        
        error_page   405 =200 @405;
        location @405 {
            return 200;
        }
    
        # Pass altered request body to a backend
        location @python {
            proxy_read_timeout 3000;
            proxy_connect_timeout 3000;
            proxy_pass   http://121.201.116.242:9999;
            #return 200;
        }
         
         location /hls { 
           types {
             application/vnd.apple.mpegurl m3u8;
             video/mp2t ts;
             video/mp4                            f4p f4v m4v mp4; 
             image/bmp                            bmp; 
             image/gif                            gif; 
             image/jpeg                            jpeg jpg; 
             image/png                            png; 
             image/svg+xml                        svg svgz; 
             image/tiff                            tif tiff; 
             image/vnd.wap.wbmp                    wbmp; 
             image/webp                            webp; 
             image/x-jng                          jng; 
           }
           root /var;
           add_header Cache-Control no-cache;
           add_header Access-Control-Allow-Origin *;
         }
      }
    }

    第四步:搭建python后台站点

    主要的处理代码如下(有一些是业务处理代码,大体看upload就ok):

    # -*- coding: utf-8 -*-
    import os
    import json
    import uuid
    import threading
    import thread_manager
    import datetime
    from django.http import HttpResponse
    from django.views.decorators.csrf import csrf_exempt
    from logging_manager import single_logger
    import logging
    import traceback
    
    
    UPLOAD_FILE_PATH = '/var/hls/video/'
    ADDVIDEO_WEIBO_URL = "http://10.32.64.194:8233/api/Video/Insert"
    UPDATE_WEIBO_JSONDATA = "http://10.32.64.194:8233/api/Video/UpdateJsonData"
    VERIFY_VIDEO_TOKEN = 'http://10.32.64.194:8233/api/NoLogin/VerifyVideoToken'
    THREAD_MANAGER = thread_manager.Thread_Pool(8)
    
    @csrf_exempt
    def upload(request):
        try:
            if verify_to_weibo(request.META['QUERY_STRING']) == False:#权限验证
                content = json.dumps({
                    'message' : 'You have no authority',
                    'code' : 96
                })
                response = HttpResponse(content, content_type='application/json; charset=utf-8')
                single_logger.info('非法的调用:%s' % request.META['QUERY_STRING'])
                return response
            
            request_params = request.POST
            file_name = request_params['file.name']
            file_content_type = request_params['file.content_type']
            file_path = request_params['file.path']
            file_size = request_params['file.size']
            # save file to tmp
            today_str = datetime.date.today().strftime("%Y-%m-%d")
            new_file_name = str(uuid.uuid1())
            dir = '%s/%s' % (UPLOAD_FILE_PATH, today_str)
            isExists = os.path.exists(dir)
            if not isExists:
                os.makedirs(dir)
            new_file_path = ''.join([UPLOAD_FILE_PATH, '%s/' % today_str, new_file_name, os.path.splitext(file_name)[-1]])
            with open(new_file_path, 'a') as new_file:
                with open(file_path, 'rb') as f:
                    new_file.write(f.read())
            
            orignUrl = ''.join(['/hls/video/', '%s/' % today_str, new_file_name, os.path.splitext(file_name)[-1]])#没切片之前的播放地址
            coverImgUrl = ''.join(['/hls/video/', '%s/' % today_str, new_file_name, '.jpg'])#封面图片下载地址
            coverImgPath = ''.join(['/var/hls/video/', '%s/' % today_str, new_file_name, '.jpg'])#封面图片存储地址
            playTime = getFileTimes(new_file_path)#视频的播放时长
            return_data = json.loads(addVideoToWeibo(orignUrl, coverImgUrl, file_name.split('.')[-1], file_size, new_file_path, playTime))
            
            mdu3 = os.system('sh /home/test/plugflow.sh %s' % new_file_name)
            content = json.dumps({
                'content_type': file_content_type,
                'orignUrl': orignUrl,
                'size': file_size,
                'playTime': playTime,
                'guid': return_data['data']['videoData']['guid'],
                'mdu3': '',
                'coverImgUrl' : coverImgUrl,
                'code' : 0
            })
            response = HttpResponse(content, content_type='application/json; charset=utf-8')
            os.system('ffmpeg -i %s -y -f  image2  -ss 1 -vframes 1  %s' % (new_file_path, coverImgPath))
            THREAD_MANAGER.add_work(function=cutVideo, param=(new_file_name, return_data['data']['videoData']['guid'], '/hls/video/%s/index.m3u8' % new_file_name))
            return response
        except BaseException as e:
            msg = traceback.format_exc()
            single_logger.error(msg)
            content = json.dumps({
                'message' : 'internal error',
                'code' : 91
            })
            response = HttpResponse(content, content_type='application/json; charset=utf-8')
            return response
    
    def verify_to_weibo(request_params):
        email, token = ('', '')
        import urllib
        import urllib2
        for parm in request_params.split('&'):
            if 'email' in parm:
                email = parm.split('=')[-1].strip()
            if 'token' in parm:
                token = parm.split('=')[-1].strip()
        values = {"email":email,"token":token}
        data = urllib.urlencode(values) 
        request = urllib2.Request( '%s?%s' % (VERIFY_VIDEO_TOKEN, data))
        response = urllib2.urlopen(request)
        return_data = json.loads(response.read())
        return return_data["data"]["correct"]
    
    def getFileTimes(filename):   
        from moviepy.editor import VideoFileClip  
        clip = VideoFileClip(filename)  
        return int(clip.duration) 
    
    
    
    #把视频相关数据添加到文件表中
    def addVideoToWeibo(orignUrl, coverImgUrl, format, length, path, playTime):
        import urllib
        import urllib2
        values = {"orignUrl":orignUrl,"coverImgUrl":coverImgUrl,"format":format,"length":length,"path":path,"playTime":playTime}
        data = urllib.urlencode(values) 
        request = urllib2.Request(ADDVIDEO_WEIBO_URL, data)
        response = urllib2.urlopen(request)
        return response.read()
    
    #视频切片
    def cutVideo((fileName, guid, m3u8Url)):
        today_str = datetime.date.today().strftime("%Y-%m-%d")
        os.system('sh /home/test/plugflow.sh %s %s' % (today_str, fileName))
        if os.path.exists('/var%s' % m3u8Url):
            updateVideoToWeibo(guid, m3u8Url)
    
    #把切片好的视频地址更新到视频的文件表
    def updateVideoToWeibo(guid, m3u8Url):
        import urllib
        import urllib2
        values = {"guid":guid, "m3u8Url":m3u8Url}
        data = urllib.urlencode(values) 
        request = urllib2.Request(UPDATE_WEIBO_JSONDATA, data)
        response = urllib2.urlopen(request)
        return response.read()
        
    '''def timeConvert(size):# 单位换算  
        M, H = 60, 60**2  
        if size < M:  
            return str(size)+'S'  
        if size < H:  
            return '%sM%sS'%(int(size/M),int(size%M))  
        else:  
            hour = int(size/H)  
            mine = int(size%H/M)  
            second = int(size%H%M)  
            tim_srt = '%sH%sM%sS'%(hour,mine,second)  
        return tim_srt  
    '''
  • 相关阅读:
    用户代理检测浏览器、引擎、平台、设备、游戏系统
    浏览器检测
    js 实现table每列可左右拖动改变列宽度 【转载】
    检测flash是否安装及版本号
    高亮显示搜索的关键词(二)
    修改鼠标选中文本的样式
    高亮显示搜索的关键词
    让站长在SEO时更得心应手的六个细节
    JQuery图片延迟加载插件,动态获取图片长宽尺寸
    jquery 图片背景透明度(支持IE5/IE6/IE7)
  • 原文地址:https://www.cnblogs.com/jiangjing/p/8427790.html
Copyright © 2011-2022 走看看