一、PHP下的Swoole模块安装
安装的话去官网 -> https://www.swoole.com/ 根据提示一步一步操作即可
二、弹幕的实现
好了,看到这就代表已经安装好了 Swoole,那就来简单说一下下弹幕的实现
额 其实弹幕实现的话有一个现成的哦,叫做,,(等下我想想) Jquery_danmujs是叫这个吧,嗯, https://github.com/chiruom/jquery.danmu.js 放上链接 下载就行了
三、Swoole的消息传输
弹幕嘛 就可以给他看作多个人的聊天室,这里的话后台就用到Swoole,前台webscoket
四、代码
貌似也没什么说的直接写代码吧,前端播放视频我用的是video-js
<?php
/*
* --创建socket连接
*
*
* */
class ws_server{
public $live_id = null; //获取直播间id
public $fd = null; //获取用户fd
public $redis_fd = null; //储存用户分类fd用户分类用户
public function __construct(){
$this->server();
}
public function server(){
$server = new swoole_websocket_server("0.0.0.0",9502); //定义swoole链接
//设置 swoole进程数以及日志目录
$server -> set([
'worker_num' => 5, //设置进程数为5
'daemonize' => true, //设置为守护进程-这样会在后台运行
'log_file' => __DIR__ . '/swoolelog.log', //设置日志目录
]);
$server -> on("open",function ($server,$request){
//var_dump($request);
$live_id = $request -> server["query_string"];
$this->live_id = substr($live_id,stripos($live_id,"=")+1); //获取直播id
$msg = '{ "text":"Master welcome","color":"undefined","size":1,"position":"0"'; //这里json格式不要写完因为要做实时的就得留一个时间让客户端加上去
echo date("Y-m-d:H:i:s")." - ".$request -> fd.PHP_EOL;
$server -> push($request->fd,$msg); //加入房间时发送提示
$this->fd = $request -> fd;
$this->redis_model(1,$server); //将用户的fd 存入redis列表
});
$server -> on('message',function ($server,$request){
foreach ($this->redis_fd as $key => $value){ //循环查询redis所存用户数据 并发送内容
$server -> push($value,$request -> data);
}
});
$server -> on('close',function ($server,$request){
$this->redis_model(2,$server); //用户退出时将 用户fd剔除redis列表
echo date("Y-m-d:H:i:s")."-".$this -> fd.PHP_EOL;
});
$server -> start(); //开启进程(服务)
}
public function redis_model($model,$server)
{
$redis = new Redis();
$redis -> connect("127.0.0.1",6379); //创建redis连接
if($redis -> ping()){
if($model == 1){
if($this->fd != null && $this->live_id != null){
$this->redis_fd = $redis -> lRange($this->live_id,0,-1);
if(!empty($this->redis_fd)){ //如果redis列表存在既要判断列表内是否存在该值
if(!in_array($this->fd,$this->redis_fd)){
$redis -> rPushx($this->live_id,$this->fd);
}
}else{
$redis -> lPush($this->live_id,$this->fd);
}
$this->redis_fd = $redis -> lRange($this->live_id,0,-1);
}else{
$server -> push($this->fd,'{ "text":"连接服务器失败","color":"undefined","size":"1","position":"0"');
}
}else if($model == 2){
$redis -> lRem($this->live_id, $this->fd, 0); //将用户剔除redis列表
}
}else{
$server -> push($this->fd,'{ "text":"连接服务器失败","color":"undefined","size":"1","position":"0"');
echo "redis_error!".PHP_EOL;
}
}
}
new ws_server();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>弹幕made by diligentyang</title>
<style>
body {
font-family: "Microsoft YaHei" ! important;
font-color:#222;
}
pre {
line-height: 2em;
font-family: "Microsoft YaHei" ! important;
}
h4 {
line-height: 2em;
}
#danmuarea {
position: relative;
background: #222;
width:800px;
height: 445px;
margin-left: auto;
margin-right: auto;
}
.center {
text-align: center;
}
.ctr {
font-size: 1em;
line-height: 2em;
}
</style>
<script src="http://libs.baidu.com/jquery/2.1.4/jquery.min.js"></script>
<script src="../dist/jquery.danmu.min.js"></script>
</head>
<body class="center">
Demo<br><br>
<!--黑背景和弹幕区-->
<div id="danmuarea">
<div id="danmu" >
</div>
</div>
<!--控制区-->
<div class="ctr" >
<button type="button" onclick="pauser()">弹幕暂停</button>
<button type="button" onclick="resumer() ">弹幕继续</button>
显示弹幕:<input type='checkbox' checked='checked' id='ishide' value='is' onchange='changehide()'>
弹幕透明度:
<input type="range" name="op" id="op" onchange="op()" value="100"> <br>
当前弹幕运行时间(秒):<span id="time"></span>
<!--设置当前弹幕时间(秒): <input type="text" id="set_time" max=20 />
<button type="button" onclick="settime()">设置</button>-->
<br>
发弹幕:
<select name="color" id="color" >
<option value="white">白色</option>
<option value="red">红色</option>
<option value="green">绿色</option>
<option value="blue">蓝色</option>
<option value="yellow">黄色</option>
</select>
<select name="size" id="text_size" >
<option value="1">大文字</option>
<option value="0">小文字</option>
</select>
<select name="position" id="position" >
<option value="0">滚动</option>
<option value="1">顶端</option>
<option value="2">底端</option>
</select>
<input type="textarea" id="text" max=300 />
<button type="button" onclick="send()">发送</button>
</div>
<script>
//WebSocket
const websocket= new WebSocket('你的ws服务端地址');
websocket.onopen = function (evt) {
console.log("Connected to WebSocket server.");
//连上之后就打开弹幕
$('#danmu').danmu('danmuResume');
};
websocket.onclose = function (evt) {
console.log("Disconnected");
};
websocket.onmessage = function (evt) {
var time = $('#danmu').data("nowTime")+1;
var text_obj= event.data +',"time":'+time+'}';//上面说到json并没有写完要预留一个时间,这里加上去就行了
console.log(text_obj);
var new_obj=eval('('+text_obj+')');
$('#danmu').danmu("addDanmu",new_obj);//添加弹幕
};
websocket.onerror = function (evt, e) {
console.log('Error occured: ' + evt.data);
};
//初始化
$("#danmu").danmu({
left:0,
top:0,
height:"100%",
width:"100%",
speed:20000,
opacity:1,
font_size_small:16,
font_size_big:24,
top_botton_danmu_time:6000
});
//一个定时器,监视弹幕时间并更新到页面上
function timedCount(){
$("#time").text($('#danmu').data("nowTime"));
t=setTimeout("timedCount()",50)
}
timedCount();
function starter(){
$('#danmu').danmu('danmuStart');
}
function pauser(){
$('#danmu').danmu('danmuPause');
}
function resumer(){
$('#danmu').danmu('danmuResume');
}
function stoper(){
$('#danmu').danmu('danmuStop');
}
function getime(){
alert($('#danmu').data("nowTime"));
}
function getpaused(){
alert($('#danmu').data("paused"));
}
//发送弹幕,使用了文档README.md第7节中推荐的方法
function send(){
var text = document.getElementById('text').value;
var color = document.getElementById('color').value;
var position = document.getElementById('position').value;
var size =document.getElementById('text_size').value;
var text_obj='{ "text":"'+text+'","color":"'+color+'","size":"'+size+'","position":"'+position+'"';
//利用websocket发送
websocket.send(text_obj);
//清空相应的内容
document.getElementById('text').value='';
}
//调整透明度函数
function op(){
var op=document.getElementById('op').value;
$('#danmu').danmu("setOpacity",op/100);
}
//调隐藏 显示
function changehide() {
var op = document.getElementById('op').value;
op = op / 100;
if (document.getElementById("ishide").checked) {
$("#danmu").danmu("setOpacity",1)
} else {
$("#danmu").danmu("setOpacity",0)
}
}
//设置弹幕时间
function settime(){
var t=document.getElementById("set_time").value;
t=parseInt(t)
$('#danmu').danmu("setTime",t);
}
</script>
</body>
</html>
html的话我就只写弹幕层了因为我比较懒
最后附上demo链接 http://www.o4d.cn/live/1.html