美文网首页利用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