Python实现视频上传与播放Web服务功能详解

使用Flask构建视频上传和播放Web服务
在当今数字化时代,文件上传和下载功能已经成为众多Web应用不可或缺的一部分。无论是社交媒体平台、在线教育网站还是企业级应用,用户都希望能够方便快捷地上传和分享他们的视频文件。本文将详细介绍如何使用Python的Flask框架创建一个简单的视频上传服务,并允许用户通过API访问这些视频。

为什么选择Flask?
Flask是一个轻量级的Python Web框架,它易于使用且具有高度灵活性,非常适合快速开发小型到中型的应用程序。通过Flask,我们可以轻松实现文件上传、存储以及通过API提供文件访问的功能。

准备工作

首先,确保你已经安装了Python和pip。然后,我们需要安装Flask框架以及用于处理Base64编码的库:

pip install Flask
实现步骤
1. 导入必要的库

我们从导入必要的库开始,包括base64用于处理Base64编码的数据,timeos用于生成路径和目录操作,以及Flask相关的模块。

import base64
import time
import os
from flask import Flask, request, jsonify, send_file, send_from_directory
2. 初始化Flask应用

接下来,初始化我们的Flask应用并设置文件存储路径和允许的文件格式。

app = Flask(__name__)

# 设置存储位置
UPLOAD_PATH = '/datafile/azhm-mp4'

# 设置允许上传的视频格式
ALLOWED_EXTENSIONS = {'mp4', 'avi', 'mov', 'mkv', 'flv', 'wmv'}
3. 定义辅助函数

定义一个辅助函数allowed_file来检查上传的文件是否符合规定的格式。

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
4. 实现上传接口

实现两个不同的上传接口:一个接受二进制文件上传,另一个接受Base64编码的字符串数据。

@app.route('/upload', methods=['POST'])
def upload_file():
    try:
        if 'file' not in request.files:
            return jsonify({"error": "未提供文件部分"}), 400
        file = request.files['file']
        if file.filename == '':
            return jsonify({"error": "未选择文件"}), 400
        if file and allowed_file(file.filename):
            current_date = time.strftime("%Y%m%d", time.localtime())
            dir_path = f'{UPLOAD_PATH}/{current_date}'
            if not os.path.exists(dir_path):
                os.makedirs(dir_path)
                print(f"目录不存在,已创建{dir_path}")
            filename = file.filename
            file_path = f'{dir_path}/' + filename
            file.save(file_path)  # 保存文件到服务器指定目录
            return jsonify({"message": "上传成功", "filepath": f'{current_date}/{filename}'}), 200
        else:
            return jsonify({"error": "无效的文件类型或文件大小超过10MB"}), 400
    except Exception as e:
        return jsonify({"error": str(e)}), 500

@app.route('/uploadStr', methods=['POST'])
def uploadStr_file():
    try:
        data = request.form
        if 'file' not in data or 'filename' not in data:
            return jsonify({"error": "未提供文件或文件名"}), 400
        file_base64 = data['file']
        filename = data['filename']
        if not allowed_file(filename):
            return jsonify({"error": "无效的文件类型"}), 400
        file_bytes = base64.b64decode(file_base64)
        current_date = time.strftime("%Y%m%d", time.localtime())
        dir_path = f'{UPLOAD_PATH}/{current_date}'
        if not os.path.exists(dir_path):
            os.makedirs(dir_path)
            print(f"目录不存在,已创建{dir_path}")
        file_path = f'{dir_path}/' + filename
        with open(file_path, 'wb') as f:
            f.write(file_bytes)
        return jsonify({"message": "上传成功", "filepath": f'{current_date}/{filename}'}), 200
    except base64.binascii.Error:
        return jsonify({"error": "无效的Base64字符串"}), 400
    except Exception as e:
        return jsonify({"error": str(e)}), 500
5. 实现视频获取接口

最后,我们提供一个接口让用户能够直接通过URL访问他们上传的视频。

@app.route('/get_mp4', methods=['GET'])
def get_video():
    video_path_name = request.args.get('name')
    return send_from_directory(UPLOAD_PATH, video_path_name, mimetype='video/mp4')

@app.route('/v/<path:video_path_name>', methods=['GET'])
def get_video1(video_path_name):
    return send_from_directory(UPLOAD_PATH, video_path_name, mimetype='video/mp4')
6. 启动应用

在项目的主文件中添加启动命令,让Flask应用运行起来。

if __name__ == '__main__':
    print(f'文件服务.启动成功')
    app.run('0.0.0.0', '9050')

项目启动
1、上传文件Base64
![在这里插入图片描述](https://i3.wp.com/i-blog.csdnimg.cn/direct/14f1a5f6079449be83583e3b498b18d8.png
2、流式上传

3、查看视频两种方式
(1)get_mp4?name=路径

(2)v/路径

完整源码

import base64
import time
import os
from flask import Flask, request, jsonify, send_file, send_from_directory

app = Flask(__name__)

# 设置存储位置
# UPLOAD_PATH = 'D:/datafile/azhm-mp4'
UPLOAD_PATH = '/datafile/azhm-mp4'

# 设置允许上传的视频格式
ALLOWED_EXTENSIONS = {'mp4', 'avi', 'mov', 'mkv', 'flv', 'wmv'}


# 检查文件扩展名是否在允许的列表中
def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS


@app.route('/upload', methods=['POST'])
def upload_file():
    try:
        if 'file' not in request.files:
            return jsonify({"error": "未提供文件部分"}), 400
        file = request.files['file']
        if file.filename == '':
            return jsonify({"error": "未选择文件"}), 400
        if file and allowed_file(file.filename):

            # 获取当前日期
            current_date = time.strftime("%Y%m%d", time.localtime())
            dir_path = f'{UPLOAD_PATH}/{current_date}'
            # 检查路径是否存在,如果不存在,则创建目录
            if not os.path.exists(dir_path):
                os.makedirs(dir_path)
                print(f"目录不存在,已创建{dir_path}")

            filename = file.filename
            file_path = f'{dir_path}/' + filename
            file.save(file_path)  # 保存文件到服务器指定目录
            return jsonify({"message": "上传成功", "filepath": f'{current_date}/{filename}'}), 200
        else:
            return jsonify({"error": "无效的文件类型或文件大小超过10MB"}), 400
    except Exception as e:
        return jsonify({"error": str(e)}), 500


@app.route('/uploadStr', methods=['POST'])
def uploadStr_file():
    try:
        data = request.form
        if 'file' not in data or 'filename' not in data:
            return jsonify({"error": "未提供文件或文件名"}), 400

        file_base64 = data['file']
        filename = data['filename']

        if not allowed_file(filename):
            return jsonify({"error": "无效的文件类型"}), 400

        file_bytes = base64.b64decode(file_base64)

        # 获取当前日期
        current_date = time.strftime("%Y%m%d", time.localtime())
        dir_path = f'{UPLOAD_PATH}/{current_date}'
        # 检查路径是否存在,如果不存在,则创建目录
        if not os.path.exists(dir_path):
            os.makedirs(dir_path)
            print(f"目录不存在,已创建{dir_path}")

        file_path = f'{dir_path}/' + filename
        with open(file_path, 'wb') as f:
            f.write(file_bytes)

        return jsonify({"message": "上传成功", "filepath": f'{current_date}/{filename}'}), 200

    except base64.binascii.Error:
        return jsonify({"error": "无效的Base64字符串"}), 400
    except Exception as e:
        return jsonify({"error": str(e)}), 500


@app.route('/get_mp4', methods=['GET'])
def get_video():
    video_path_name = request.args.get('name')
    return send_from_directory(UPLOAD_PATH, video_path_name, mimetype='video/mp4')


@app.route('/v/<path:video_path_name>', methods=['GET'])
def get_video1(video_path_name):
    return send_from_directory(UPLOAD_PATH, video_path_name, mimetype='video/mp4')


if __name__ == '__main__':
    print(f'文件服务.启动成功')
    app.run('0.0.0.0', '9050')

结论

通过上述步骤,我们成功创建了一个基于Flask的视频上传和访问服务。这个简单的例子展示了如何利用Python和Flask框架快速搭建起一个实用的后端服务。无论你是想为自己的项目增加文件上传功能,还是希望学习更多关于Flask的应用开发知识,这个例子都是一个很好的起点。未来,你可以进一步扩展此服务,比如增加身份验证、限制文件大小等功能,以满足更复杂的需求。

作者:大博士.J

物联沃分享整理
物联沃-IOTWORD物联网 » Python实现视频上传与播放Web服务功能详解

发表回复