Python实现视频上传与播放Web服务功能详解
使用Flask构建视频上传和播放Web服务
在当今数字化时代,文件上传和下载功能已经成为众多Web应用不可或缺的一部分。无论是社交媒体平台、在线教育网站还是企业级应用,用户都希望能够方便快捷地上传和分享他们的视频文件。本文将详细介绍如何使用Python的Flask框架创建一个简单的视频上传服务,并允许用户通过API访问这些视频。
为什么选择Flask?
Flask是一个轻量级的Python Web框架,它易于使用且具有高度灵活性,非常适合快速开发小型到中型的应用程序。通过Flask,我们可以轻松实现文件上传、存储以及通过API提供文件访问的功能。
准备工作
首先,确保你已经安装了Python和pip。然后,我们需要安装Flask框架以及用于处理Base64编码的库:
pip install Flask
实现步骤
1. 导入必要的库
我们从导入必要的库开始,包括base64
用于处理Base64编码的数据,time
和os
用于生成路径和目录操作,以及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
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