視訊彈幕帶時間同步demo
阿新 • • 發佈:2018-11-08
婚慶現場或年會上有在大屏上一直滾動的視訊,來賓關注公眾號後就可以直接傳送留言上牆了,看起來貌似好好玩的樣子
彈幕一般利用websocket和後臺server建立連線然後傳送/接收資料,這裡使用H5來做前臺頁面,只是一個demo沒有做過多的美化和優化,特別是server端程式碼,一旦資訊多了會撐爆記憶體,如果需要在實際中使用還需進一步處理。
前臺展示主要用到了websocket,基本上看原始碼就能明白,核心程式碼如下:
<script>
//WebSocket
var wsServer = 'ws://172.17.154.228:7181';
var websocket= new WebSocket(wsServer);
websocket.onopen = function (evt) {
console.log("Connected to WebSocket server.");
/*websocket.send("gaga");*/
//連上之後就開啟彈幕
$('#danmu').danmu('danmuResume');
};
websocket.onclose = function (evt) {
console.log("Disconnected") ;
};
websocket.onmessage = function (evt) {
console.log('Retrieved data from server: ' + evt.data);
var time = $('#danmu').data("nowTime")+1;
var text_obj = evt.data.indexOf("time") == -1 ? evt.data + ',"time":' + time + '}' : evt.data;//獲取加上當前時間
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 time = $('#danmu').data("nowTime")+1;
var size =document.getElementById('text_size').value;
var text_obj='{ "text":"'+text+'","color":"'+color+'","size":"'+size+'","position":"'+position+'","time":'+time+'}';
//為了處理簡單,方便後續加time,和isnew,就先醬紫發一半吧。
//注:time為彈幕出來的時間,isnew為是否加邊框,自己發的彈幕,常理上來說是有邊框的。
//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>
在服務端儲存每個進來的連線,然後將接收到的訊息分發出去
server.Start(socket =>
{
socket.OnOpen = () =>
{
Console.WriteLine("Open!");
foreach(string msg in readBuffer)
{
socket.Send(msg);
}
allSockets.Add(socket);
};
socket.OnClose = () =>
{
Console.WriteLine("Close!");
allSockets.Remove(socket);
if (allSockets.Count == 0)
{
StreamWriter sw = new StreamWriter(recordPath);
foreach (string msg in readBuffer)
sw.WriteLine(msg);
sw.Close();
}
};
socket.OnMessage = message =>
{
Console.WriteLine(message);
readBuffer.Add(message);
allSockets.ToList().ForEach(s => s.Send(message.Substring(0,message.LastIndexOf(','))));
};
socket.OnBinary = file => {
string path = ("D:\\test.txt");
//建立一個檔案流
FileStream fs = new FileStream(path, FileMode.Create);
//將byte陣列寫入檔案中
fs.Write(file, 0, file.Length);
fs.Close();
};
});
var input = Console.ReadLine();
while (input != "exit")
{
foreach (var socket in allSockets.ToList())
{
socket.Send(input);
}
input = Console.ReadLine();
}
附加:原始碼傳送門