美文网首页利用Flask搭建微电影视频网站
利用Flask搭建微电影视频网站(十五):实现电影弹幕

利用Flask搭建微电影视频网站(十五):实现电影弹幕

作者: 啃饼小白 | 来源:发表于2018-09-18 07:37 被阅读32次

关于博主

努力与运动兼备~~~有任何问题可以加我好友或者关注微信公众号,欢迎交流,我们一起进步!

                  微信公众号:  啃饼思录
                   QQ: 2810706745(啃饼小白)

写在前面

本篇笔记,我们将利用FLask 结合Redis消息队列来实现电影弹幕这个功能以及部分代码的优化。

本篇笔记对应上传的仓库为:https://github.com/licheetools/movie对应第十五篇。

电影弹幕的实现

使用到的内容

我们将使用到的内容有:
模型: Movie
表单: 无
请求方法: GET ,POST
访问控制: 无
消息队列: Redis
Flask第三方扩展: Flask-Redis
弹幕播放器插件: dplayer.js(开源)

1、安装Flask-Redis

直接在pycharm里面安装Flask-Redis即可,或者使用下面的命令安装稳定的Flask-Redis也是可以的:

pip install flask-redis

2、安装Redis,绑定本地ip

点击这里直接安装windows下redis安装,如果不行就下载这个:redis-windows
然后点击这里安装redis可视化工具:redis desktop manager的安装过程。接着在dos命令下输入ifconfig查询本地局域网ip地址,然后进行连接:

如果连接测试不通过需要在conf文件里面绑定本地Ip:

取消注释bind,记住两个文件都要做ip的绑定!

之后重新启动redis服务即可!如果还是连接不上,那就要检查是否存在绑定多个IP的情况以及密码是不是正确。

不清楚的可以查看这里:
用Redis Desktop Manager连接Redis(Windows)

3、安装dplayer.js

点击这里dplayer.js官网或者这里dplayer.js下载安装GitHub源码进行安装。如果你觉得麻烦,可以直接在我的GitHub上下载源码,我里面都有,还进行了部分内容的修改。

4、定义弹幕函数

打开home/views.py文件,我们复制页面详情页面的代码,然后把play修改为video即可,其余不变:

# 弹幕播放器
@home.route('/video/<int:id>/<int:page>/', methods=["GET", "POST"])
def video(id=None, page=None):
    movie = Movie.query.join(Tag).filter(
        Tag.id == Movie.tag_id,
        Movie.id == int(id)
    ).first_or_404()

    if page is None:
        page = 1
        # 查询的时候关联标签,采用join来加进去,多表关联用filter,过滤用filter_by
    page_data = Comment.query.join(
        Movie
    ).join(
        User
    ).filter(
        Movie.id == movie.id,
        User.id == Comment.user_id
    ).order_by(
        Comment.addtime.desc()
    ).paginate(page=page, per_page=10)

    movie.playnum = movie.playnum + 1
    form = CommentForm()
    if "user" in session and form.validate_on_submit():
        data = form.data
        comment = Comment(
            content=data["content"],    # 左侧字段与数据库Comment字段保持一致
            movie_id=movie.id,
            user_id=session["user_id"]
        )
        db.session.add(comment)
        db.session.commit()
        movie.commentnum = movie.commentnum + 1
        db.session.add(movie)
        db.session.commit()
        flash("添加评论成功!", "ok")
        return redirect(url_for("home.video", id=movie.id, page=1))
        movie.commentnum = movie.commentnum+1
    db.session.add(movie)
    db.session.commit()
    return render_template("home/video.html", movie=movie, form=form, page_data=page_data)

5、新建paly页面

在templates/home文件夹下面新建一个paly.html页面,然后把play.html全部代码拷贝进去,把原本关于jwplayer部分的代码都可以去掉:包括css和script,以及修改页面链接:

还要添加script:

<script src="{{ url_for('static', filename='jwplayer/jwplayer.js') }}"></script>

6、引入弹幕css

在video.html页面的css里面引入我们DPlayer的css文件:

<link rel="stylesheet" href="{{ url_for('static',filename='dplayer/dist/DPlayer.min.css') }}">
<script src="{{ url_for('static',filename='dplayer/plugin/flv.min.js') }}"></script>
<script src="{{ url_for('static',filename='dplayer/plugin/hls.min.js') }}"></script>
<script src="{{ url_for('static',filename='dplayer/dist/DPlayer.min.js') }}"></script>

7、修改弹幕的样式

   .dplayer-comment-setting-type>label{
    display: inline;}

位置不要放错了,应当在这里:

8、定义播放器的样式

<div id="dplayer1" style="height:500px;width: 774px;"></div>

打开video.html,我们用上面的代码替换图中的:

9、播放页面script

继续配置我们的video.html页面:

<script>
    var dp1 = new DPlayer({
        element: document.getElementById('dplayer1'),
        video: {
            url: "{{ url_for('static',filename='uploads/'+movie.url) }}",
        },
        danmaku: {
            id: '{{ movie.id }}',
            api: "/tm/"
        }
    });
</script>

10、处理弹幕

我们点击Dplayer官网,然后F12开启调试,点击NetWork,再点击XHR,就发现弹幕发送及加载数据的接口,其实我们的弹幕是json字符串,所以我们开始进行配置:打开我们项目的--init--.py文件,导入安装好的FlaskRedis,使用的命令如下:

from flask_redis import FlaskRedis

接着定义我们Redis的url格式:

app.config["REDIS_URL"] = "redis://192.0.0.1:6379/0"  # 后面是你的ip

然后定义一个redis对象

rd = FlaskRedis(app)

11、views.py引入redis对象

我们在views.py引入redis对象,并且我们需要新定义一个弹幕接口,就是我们之前在video.html定义的tm

from app import rd
from flask import Response


# 处理弹幕消息
@home.route("/tm/", methods=["GET", "POST"])
def tm():
    import json
    if request.method == "GET":   # 获取弹幕
        id = request.args.get('id')   # 用id来获取弹幕消息队列
        key = "movie" + str(id)   # 拼接形成键值用于存放在redis队列中
        if rd.llen(key):
            msgs = rd.lrange(key, 0, 2999)
            res = {
                "code": 1,
                "danmaku": [json.loads(v) for v in msgs]
            }
        else:
            res = {
                "code": 1,
                "danmaku": []
            }
        resp = json.dumps(res)
    if request.method == "POST":   # 添加弹幕
        data = json.loads(request.get_data())
        msg = {
            "__v": 0,
            "author": data["author"],
            "time": data["time"],
            "text": data["text"],
            "color": data["color"],
            "type": data['type'],
            "ip": request.remote_addr,
            "_id": datetime.datetime.now().strftime("%Y%m%d%H%M%S") + uuid.uuid4().hex,
            "player": [
                data["player"]
            ]
        }
        res = {
            "code": 1,
            "data": msg
        }
        resp = json.dumps(res)
        rd.lpush("movie" + str(data["player"]), json.dumps(msg))   # 将添加的弹幕推入redis的队列中
    return Response(resp, mimetype='application/json')

然后你就可以打开页面进行测试了,去看看你的弹幕功能是不是实现了呢!

代码优化

其实我们这样写的代码是具有部分Bug的,我们需要修复一下,主要包括:头像判断,关键词搜索分页,以及电影右侧播放页面滚动条等。

头像判断

你首先去注册一个用户,然后登入,最后去评论一个电影,点击提交就会出现这样的错误:

builtins.TypeError
TypeError: must be str, not NoneType

那是因为我们没有给他一个默认的头像,所以才会出现这样的错误,我们打开我们的play.html页面,我们对头像进行判断一下:

{% if v.user.face %}
      <img alt="50x50"
       src="{{ url_for('static', filename='uploads/users/'+v.user.face) }}"
         class="img-circle"
         style="border:1px solid #abcdef;width: 50px;">
{% else %}
       <img alt="50x50"
            data-src="holder.js/50x50"
             class="img-circle"
           style="border:1px solid #abcdef;width: 50px;">
{% endif %}

就是这样:

然后刷新就不会报错了,不过呢你还要去comments(home/comments.htmladmin/comment_list.html),admin/user_list.htmladmin/user_view.htmlvideo.html页面进行同样的配置(所有页面都点击一下,怕遗忘,简单点可以搜索一下,一共7个页面需要配置):

注意一下,我们在admin/user_view.html里面配置头像为100x100:

接下来我们继续关键词搜索分页的配置。

关键词搜索分页

我们发现在输入关键词回车之后可以显示搜索信息,但是点击搜索页面底部的首页时,key就没了,所以我们需要保留。我们在ui文件夹下面新建一个s_page.html页面,把home_page.html代码全部拷贝进去,然后去掉所有的id,添加?key={{ data.key }}即可:

既然这样创建了s_page.html,那别忘记修改search.html页面的引用了:

{% import "ui/s_page.html" as pg %}

我们还要打开home/views.py文件,返回我们的key:

 page_data.key = key

就是这样:

然后可以试试,看看我们的关键词搜索分页是否没有问题了呢。

电影右侧播放页面滚动条

当电影详情页信息过多时,我们需要设置滚动条:

这个挺简单的,只需要添加滚动即可:(有3个页面,搜索一下,然后替换一下即可)

<div class="panel-body" style="height:459px;overflow: scroll">

把上面的代码替换图中所指示的信息即可:

至此,我们本篇关于电影弹幕以及部分代码优化的介绍就到此为止了,感谢你的赏阅。

本篇笔记对应上传的仓库为:https://github.com/licheetools/movie对应第十五篇。

相关文章

网友评论

    本文标题:利用Flask搭建微电影视频网站(十五):实现电影弹幕

    本文链接:https://www.haomeiwen.com/subject/vhyagftx.html