基于 Flask 的在线视频播放器

项目描述

使用 Flask 实现的简单网页视频播放器。
开发准备:Python3

功能简介

  1. 在线视频播放
  2. 视频列表浏览
  3. 上传共享视频
  4. 基于socket的多人弹幕评论

功能演示

项目结构

Vision
—— blueprints (注册蓝图)
—— sockets (内嵌 socket ,用于实现在线评论等功能)
—— static (静态资源目录)
———— css ( css 文件)
———— js ( javascript 文件)
———— img (静态图片资源)
———— image (视频缩略图)
———— video (视频源文件)
———— upload (保存视频格式文件)
—— templates (网页模板文件)
—— utils (功能文件夹)
—— app.py (系统启动文件)

1. 上传视频

  • 定义/play/upload接口,用于提供上传视频页面。
  • 定义/play/music/upload接口,用于网页通过POST请求上传视频到后台。
bp = Blueprint('play',__name__,url_prefix="/play")

@bp.route('/upload', methods=['GET'])
def upload():
    return render_template('play/upload.html')

@bp.route('/music/upload', methods=['POST'])
def doupload():
    id = random_name()

    # 下载视频
    video = request.files['video']
    video.save('static/video/' + id  + file_extension(video.filename))

    # 下载视频缩略图
    image = 'static/image/' + id + '.jpg'
    capture('static/video/' + id  + file_extension(video.filename), image)

    data = {
        "author": request.form["author"],
        "date": now(),
        "image": "/" + image,
        "video": "/static/video/" + id  + file_extension(video.filename),
        "title": request.form["title"]
        "description": request.form["description"]
    }
    # 保存视频格式化文件
    with open("static/upload/" + id + ".json", "w") as f:
        json.dump(data, f)

    return redirect(url_for('play.index'))

default.json(视频保存格式):

{
 "author": "管理员",
 "date": "2019-03-21 15:33",
 "image": "/static/image/wsl.png",
 "video": "/static/video/wsl.mp4",
 "title": "一笑倾城",
 "description": "我想和你唱 汪苏泷"
}

提示:所有格式化文件均保存在upload文件夹中。

上传视频表单:

<form style="" name="form" method="post" action="{{ url_for('play.doupload') }}" enctype="multipart/form-data">
    <a style="float:right" href="{{ url_for('play.index') }}">返回</a>
    <ul>
        <li>
            <label>分享人:</label>
            <input type="text" name="author" placeholder="请输入用户名" onblur="checkna()" autocomplete="off" required/><span class="tips" id="divname">长度1~5个字符</span>
        </li>
        <li>
            <label>标题:</label>
            <input type="text" name="title" placeholder="请输入视频标题" onblur="checkpsd1()" autocomplete="off" required/><span class="tips" id="divpd1">长度1~20个字符</span>
        </li>
        <li>
            <label>视频:</label>
            <input type="file" name="video" accept="video/mp4" required/><span>请使用mp4格式</span>
        </li>
    </ul>
    <b class="btn"><input type="submit" value="提交"/>
    <input type="reset" value="取消"/></b>
</form>

2. 滚动弹幕评论

  • 服务端

基于flask_socketio
监听用户登录(connect)、登出(disconnect)状态;
一旦监听到用户评论信息(imessage),就向客户端广播 message 信息。

from flask_socketio import emit
namespace = "/comment"

@socketio.on('imessage', namespace=namespace)
def test_message(message):
    emit('message', {'data': message['data']}, broadcast=True, namespace=namespace)

@socketio.on('connect', namespace=namespace)
def connected_msg():
    """socket client event - connected"""
    socketio.emit('message', {'data': '系统消息:欢迎进入!!!'}, namespace=namespace)
    print('client connected!')

@socketio.on('disconnect', namespace=namespace)
def disconnect_msg():
    """socket client event - disconnected"""
    socketio.emit('message', {'data': '系统消息:有人离开了!!!'}, broadcast=True, namespace=namespace)
    print('client disconnected!')
  • 客户端

基于socket.io.min.js
监听所有 message 信息,并提取内容产生滚动弹幕;
获取用户评论信息,并以 imessage 消息形式发送给服务端。

<script type="text/javascript" src="/static/js/socket.io.min.js"></script>
<script type="text/javascript">
    var namespace = '/comment';
    var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port + namespace);

    socket.on('message', function (msg) {
        $('body').barrager({'href': '#', 'info': $('<div/>').text(decodeURI(msg.data)).html()});
    });

    $("#comment").keypress(function (e) {
        if (e.which == 13) {
            socket.emit('imessage', {data: encodeURI($('#comment').val())});
            $('#comment').val('');
        }
    });
</script>

3. 项目启动入口

app.py:

from flask import *
from flask_socketio import SocketIO
from blueprints import play
from sockets import comment

app = Flask(__name__)
app.config['SECRET_KEY'] = '123456'

@app.route('/')
def index():
    return redirect(url_for("play.index"))

app.register_blueprint(play.bp)

socketio = SocketIO(app)
comment.register_comment(socketio)

if __name__ == '__main__':
    socketio.run(app, host='0.0.0.0', port=80, debug=True)

在命令行中执行python app.py,启动系统,如果提示有工具包未安装,使用pip install即可 。默认运行在80端口,你可以在浏览器中访问localhost或者电脑的局域网IP地址。启动成功后,赶紧把你的服务IP地址告诉小伙伴,一起交流分享视频资源吧!

完整项目代码可以在微信公众号【四元群】,后台回复「播放器」获取。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容