关于博主
努力与运动兼备~~~有任何问题可以加我好友或者关注微信公众号,欢迎交流,我们一起进步!
微信公众号: 啃饼思录
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.html
和admin/comment_list.html
),admin/user_list.html
,admin/user_view.html
和video.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对应第十五篇。
- 参考文章:动手实战实现Redis数据库主从同步。
网友评论