首页 > 其他分享 >flask 实现简易视频播放网站案例

flask 实现简易视频播放网站案例

时间:2024-04-15 10:48:18浏览次数:23  
标签:视频 flask app db 简易 video 播放 上传

flask 实现简易视频播放网站案例

本视频主要实现两个目的,上传视频、播放视频。

使用技术: flask、flask-sqlalchemy、layui

视频地址: https://www.bilibili.com/video/BV1QV411N7qy/

搭建项目

直接新建一个 flask 项目,然后下载 layui 的静态文件丢到 static 目录下。然后再编写视频信息展示的首页。当然在此之前需要先做好数据库的模型创建,否则视频信息展示的时候会出问题。

创建项目

直接用 pycharm 创建一个 flask 项目,创建成功后目录如下

X:\flask-video>tree /f
X:.
│ app.py

├─static
└─templates

然后访问 https://layui.dev/ ,点击直接下载之后就能得到 layui 的静态文件,将其复制到 static 目录下,完成之后的目录结构如下

X:\flask-video>tree /f
X:.
│ app.py

├─static
│ │ layui.js
│ │
│ ├─css
│ │ layui.css
│ │
│ └─font
│ iconfont.eot
│ iconfont.svg
│ iconfont.ttf
│ iconfont.woff
│ iconfont.woff2

└─templates

配置插件

1、安装插件

pip install flask-sqlalchemy

2、添加配置文件

# 配置 SQLite 数据库, 默认存放在 app instance 文件夹下  
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///flask-video.db"  
# 图片默认的上传地址  
app.config["UPLOAD_FOLDER"] = 'static/upload/video'

3、创建实例对象

from flask_sqlalchemy import SQLAlchemy

# 创建拓展插件实例  
db = SQLAlchemy()  
# 将拓展插件对象绑定到程序实例  
db.init_app(app)

4、创建视频数据模型

import sqlalchemy as sa

class MovieORM(db.Model):
    __tablename__ = 'movie'
    id = sa.Column(sa.Integer, primary_key=True, autoincrement=True)
    name = sa.Column(sa.String(255), nullable=False)
    url = sa.Column(sa.String(255), nullable=False)
    create_at = sa.Column(sa.DateTime, default=datetime.now)

5、生成测试数据

@app.cli.command()
def create():
    db.drop_all()
    db.create_all()

    mv = MovieORM()
    mv.name = '默认演示电影'
    mv.url = '/static/upload/video/7e245fc2483742414604ce7e67c13111.mp4'
    db.session.add(mv)
    db.session.commit()

视频观看

1、后端返回数据

@app.route('/')
def hello_world():
    q = db.select(MovieORM)
    movie_list = db.session.execute(q).scalars()
    return render_template('index.html', movie_list=movie_list)

2、前端渲染基础页面

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>正心的视频播放网站</title>
    <link rel="stylesheet" href="/static/css/layui.css">
    <style>
        .title {
            margin-top: 100px;
            text-align: center;
            font-size: 52px;
        }
    </style>
</head>
<body>

<h2 class="title">正心の专属视频播放网站</h2>

<div class="layui-container">

</div>

<script src="/static/layui.js"></script>
</body>
</html>

3、渲染搜索表单

<div class="layui-form" style="width: 50%;margin: 20px auto;">
    <div class="layui-form-item">
        <div class="layui-input-group">
            <input type="text" placeholder="请输入电影名" class="layui-input">
            <div class="layui-input-suffix">
                <button type="submit" class="layui-btn" lay-submit lay-filter="demo1">点击搜索</button>
                <a href="/upload_movie" class="layui-btn layui-btn-primary layui-border-green">我要上传</a>
            </div>
        </div>
    </div>
</div>

4、渲染视频数据

<table class="layui-table" style="width: 50%;margin: 0 auto">
    <colgroup>
        <col width="120">
        <col width="180">
        <col>
    </colgroup>
    <thead>
    <tr>
        <th>电影名</th>
        <th>上传时间</th>
        <th>观看</th>
    </tr>
    </thead>
    <tbody>
    {% for movie in movie_list %}
        <tr>
            <td>{{ movie.name }}</td>
            <td>{{ movie.create_at.strftime('%Y-%m-%d %H:%M:%S') }}</td>
            <td><a href="{{ movie.url }}" class="layui-btn  layui-btn-sm">点击观看</a>
                <a href="/video_view?url={{ movie.url }}" class="layui-btn  layui-btn-sm">点击观看2</a>
            </td>
        </tr>
    {% endfor %}
    </tbody>
</table>

5、新窗口播放视频

先处理后端接口请求

@app.route('/video_view')
def video_view():
    url = request.args.get('url')
    return render_template('video_view.html', url=url)

然后再在前端进行渲染

<!--filename:video_view.html-->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>上传视频 | 正心的视频播放网站</title>
    <link rel="stylesheet" href="/static/css/layui.css">
    <style>
        .title {
            margin-top: 100px;
            text-align: center;
            font-size: 52px;
        }
    </style>
</head>
<body>
<div class="layui-container">
    <h2 class="title">视频观看</h2>
    <video style="max-width: 100%;" controls="controls" poster="{{ url }}">
        <source src="{{ url }}" type="video/mp4"/>
    </video>
</div>
<script src="/static/layui.js"></script>
</body>
</html>

视频上传

1、后端返回视频上传页面

@app.get('/upload_movie')
def upload_movie():
    return render_template('video_upload.html')

2、前端进行视频上传

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>上传视频 | 正心的视频播放网站</title>
    <link rel="stylesheet" href="/static/css/layui.css">
    <style>
        .title {
            margin-top: 100px;
            text-align: center;
            font-size: 52px;
        }
    </style>
</head>
<body>
<div class="layui-container">
    <h2 class="title">上传视频文件</h2>
    <div style="width: 50%;margin: 0 auto">
            <button type="button" class="layui-btn demo-class-accept" lay-options="{accept: 'video'}">
        <i class="layui-icon layui-icon-upload"></i>
        上传视频
    </button>
    </div>

</div>
<script src="/static/layui.js"></script>
<script>
    layui.use(function () {
        var upload = layui.upload;
        var layer = layui.layer;
        // 渲染
        upload.render({
            elem: '.demo-class-accept', // 绑定多个元素
            url: '/video_upload', // 此处配置你自己的上传接口即可
            accept: 'file', // 普通文件
            done: function (res) {
                layer.msg('上传成功');
                console.log(res);
            }
        });
    });
</script>
</body>
</html>

3、后端接受并保存视频

@app.post('/video_upload')
def upload_movie2():
    file = request.files['file']
    if file:
        filename = file.filename
        content = file.read()
        name = hashlib.md5(content).hexdigest()
        suffix = os.path.splitext(filename)[-1]
        new_filename = name + suffix
        new_path = os.path.join(app.config['UPLOAD_FOLDER'], new_filename)
        open(new_path, mode='wb').write(content)

        mv = MovieORM()
        mv.url = '/' + new_path
        mv.name = filename
        db.session.add(mv)
        db.session.commit()

    return {
        'code': 0, 'msg': '上传视频成功'
    }

项目后续

项目仅仅是一个小案例,不足的地方还有非常多,可以优化的地方也有很多

视频信息没有实现删除功能。在实现删除功能的时候,不仅是需要删除数据库中的数据,还需要删除视频文件。
视频信息没有完成修改的功能。
上传的时候没有做限制,播放的时候也没有分片加载与加密。
有些知识点在往期的文章中有写过,在这里就不赘述了。

标签:视频,flask,app,db,简易,video,播放,上传
From: https://www.cnblogs.com/HeroZhang/p/18135384

相关文章

  • 30 天精通 RxJS (19):实践范例 - 简易 Auto Complete 实作
    今天我们要做一个RxJS的经典范例-自动完成(AutoComplete),自动完成在实务上的应用非常广泛,几乎随处可见这样的功能,只要是跟表单、搜寻相关的都会看到。虽然是个很常见的功能,但多数的工程师都只是直接套套件来完成,很少有人会自己从头到尾把完整的逻辑写一次。如果有自己......
  • Go实践:用Sync.Map实现简易内存缓存系统
    介绍定义了一个Cache结构体,其中使用sync.Map作为底层数据结构来存储缓存项。Set方法用于设置缓存项,指定键、值以及过期时间。Get方法用于获取缓存项,如果缓存项存在且未过期,则返回值和true,否则返回nil和false。方法的接受者为指针类型,是为了对Cache对象进行操作,并在方法内部访问和......
  • 【Linux系统编程】libevent库实现简易tcp服务器
    libevent库实现简易tcp服务器流程分析创建socket,设置端口复用,绑定四元组,开始监听。初始化event_base结构体。编写监听事件的回调函数和客户端读事件的回调函数。初始化tcp监听事件,并加入event_base中。开始event事件处理循环。释放所有事件占用资源。释放event_base占用......
  • Flask 生产环境部署(Falsk + uWSGI + nginx)
    前言最近自己做了个Falsk小项目,在部署上服务器的时候,发现虽然不乏相关教程,但大多都是将自己项目代码复制出来,不讲核心逻辑,不太简洁,于是将自己部署的经验写成内容分享出来。uWSGI简介uWSGI:一种实现了多种协议(包括uwsgi、http)并能提供服务器搭建功能的Python包Differenc......
  • 汇编语言简易教程(13):栈缓存溢出
    汇编语言简易教程(13):栈缓存溢出当程序溢出基于堆栈的动态变量时,可能会发生堆栈缓冲区溢出。例如,如果一个程序分配并使用一个基于堆栈的本地数组,该数组包含50个元素,并且数组中存储了50个以上的元素,则会发生溢出。这种溢出通常是坏的,通常会导致程序错误,甚至可能使程序崩溃......
  • 汇编语言简易教程(14):中断与恢复
    汇编语言简易教程(14):中断与恢复从一般意义上讲,中断是工作流的暂停或保持。例如,如果您正在打电话,门铃响了,则电话通话将处于暂停状态,门将应答。销售人员被送走后,电话交谈恢复(对话中断的地方)在计算机编程中,中断也是当前正在执行的过程的暂停或保持。通常,当前进程会中断,以便可......
  • 汇编语言简易教程(15):End
    汇编语言简易教程(15):End写到这里,就告一段落了.前面的内容写起来还是比较认真的,到后面的系统调用,栈缓存,中断这些内容已经快要昏迷过去了但是我认为这篇教程能够达到预期的目标:对于汇编代码的基本阅读了解汇编的基本机制我强烈建议各位有时间能够去阅读原书,难......
  • 汇编语言简易教程(13):栈缓存溢出
    汇编语言简易教程(13):栈缓存溢出当程序溢出基于堆栈的动态变量时,可能会发生堆栈缓冲区溢出。例如,如果一个程序分配并使用一个基于堆栈的本地数组,该数组包含50个元素,并且数组中存储了50个以上的元素,则会发生溢出。这种溢出通常是坏的,通常会导致程序错误,甚至可能使程序崩溃......
  • 汇编语言简易教程(12):系统服务
    汇编语言简易教程(12):系统服务应用程序必须使用操作系统执行许多操作。此类操作包括控制台输出、键盘输入、文件服务(打开、读取、写入、关闭等)、获取时间或日期、请求内存分配等访问系统服务是应用程序请求操作系统执行某些特定操作(代表进程)的方式。更具体地说,系统调用是执......
  • 汇编语言简易教程(12):系统服务
    汇编语言简易教程(12):系统服务应用程序必须使用操作系统执行许多操作。此类操作包括控制台输出、键盘输入、文件服务(打开、读取、写入、关闭等)、获取时间或日期、请求内存分配等访问系统服务是应用程序请求操作系统执行某些特定操作(代表进程)的方式。更具体地说,系统调用是执......