Flask 构建微电影视频网站(八)

评论收藏及弹幕

实现电影评论添加及列表、数据查询实现统计播放量和评论量、jquery ajax实现收藏电影,flask结合redis消息队列实现电影弹幕,bug处理等功能。

电影评论-统计

class CommentForm(FlaskForm):
    content = TextAreaField(
        label="内容",
        validators=[
            DataRequired("请输入内容!"),
        ],
        description="内容",
        render_kw={
            "id": "input_content"
        }
    )
    submit = SubmitField(
        '提交评论',
        render_kw={
            "class": "btn btn-success",
            "id": "btn-sub"
        }
    )
@home.route("/play/<int:id>/<int:page>/", methods=["GET", "POST"])
def play(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
    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)
    form = CommentForm()
    if "user" in session and form.validate_on_submit():
        data = form.data
        comment = Comment(
            content=data["content"],
            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.play', id=movie.id, page=1))
    # 放在后面避免添加评论播放量涨2
    movie.playnum = movie.playnum + 1
    db.session.add(movie)
    db.session.commit()
    return render_template("home/play.html", movie=movie, form=form, page_data=page_data)

修改前端页面

收藏电影

@home.route("/moviecol/add/", methods=["GET"])
@user_login_req
def moviecol_add():
    """
    添加电影收藏
    """
    uid = request.args.get("uid", "")
    mid = request.args.get("mid", "")
    moviecol = Moviecol.query.filter_by(
        user_id=int(uid),
        movie_id=int(mid)
    ).count()
    # 已收藏
    if moviecol == 1:
        data = dict(ok=0)
    # 未收藏进行收藏
    if moviecol == 0:
        moviecol = Moviecol(
            user_id=int(uid),
            movie_id=int(mid)
        )
        db.session.add(moviecol)
        db.session.commit()
        data = dict(ok=1)
    import json
    return json.dumps(data)

在播放页面添加js

    <script>
        $(document).ready(function () {
            $("#btn-col").click(function () {
                var mid = {{ movie.id }};
                var uid = {{ session['user_id'] }};
                $.ajax({
                    url: "{{ url_for('home.moviecol_add') }}",
                    type: "GET",
                    data: "mid=" + mid + "&uid=" + uid,
                    dataType: "json",
                    success: function (res) {
                        if (res.ok == 1) {
                            $("#show_col_msg").empty();
                            $("#show_col_msg").append("收藏成功!");
                        } else {
                            $("#show_col_msg").empty();
                            $("#show_col_msg").append("已经收藏!");
                        }
                    }
                })
            });
        });
    </script>

电影弹幕

使用[dplayer](http://dplayer.js.org/#/)替换播放器,下载dplayer文件,拷贝到static下

@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
    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"],
            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))
    db.session.add(movie)
    db.session.commit()
    return render_template("home/video.html", movie=movie, form=form, page_data=page_data)


@home.route("/tm/v3/", methods=["GET", "POST"])
def tm():
    """
    弹幕消息处理
    """
    import json
    if request.method == "GET":
        # 获取弹幕消息队列
        id = request.args.get('id')
        # 存放在redis队列中的键值
        key = "movie" + str(id)
        if rd.llen(key):
            msgs = rd.lrange(key, 0, 2999)
            '''
            {
                "code":0,
                "data":[
                    [   
                        6.978,                  # time
                        0,                      # type
                        16777215,               # color
                        "DIYgod",               # author
                        "1111111111111111111"   # text
                    ],
                    ...
                ]
            }
            '''
            res = {
                "code": 0,
                "data": [json.loads(v) for v in msgs]
            }
        else:
            res = {
                "code": 0,
                "data": []
            }
        resp = json.dumps(res)
    if request.method == "POST":
        # 添加弹幕
        data = json.loads(request.get_data())
        '''
        请求
        author: "DIYgod"
        color: 16777215
        id: "9E2E3368B56CDBB4"
        text: "此生无悔入四月来世愿做友人"
        time: 0
        type: 0
        '''
        '''
        响应
        {
            "code":0,"
            data":{
                "_id":"5bfb561b63125e15873f8d22",
                "player":"9E2E3368B56CDBB4",
                "author":"DIYgod",
                "time":0,
                "text":"此生无悔入四月来世愿做友人",
                "color":16777215,
                "type":0,
                "ip":"222.88.236.173",
                "referer":"http://dplayer.js.org/",
                "date":1543198235766,
                "__v":0
            }
        }
        '''

        resp_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["id"]

        }
        res = {
            "code": 0,
            "data": resp_msg
        }
        resp = json.dumps(res)
        # 将添加的弹幕推入redis的队列中
        msg = [
            data["time"],
            data['type'],
            data['color'],
            data["author"],
            data["text"],
        ]

        rd.lpush("movie" + str(data["id"]), json.dumps(msg))
    return Response(resp, mimetype='application/json')

video.html中引入js和css

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

    ```
    // 获取弹幕
    <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>

安装flask-redis
pip install flask-redis

在初始化文件中进行redis链接

from flask_redis import FlaskRedis

app.config["REDIS_URL"] = "redis://localhost:6379/1"

db = SQLAlchemy(app)
rd = FlaskRedis(app)

生产环境部署

参考django部署,所需文件在项目中

posted @ 2018-11-27 21:30  寒菱  阅读(707)  评论(0编辑  收藏  举报