mirror of
https://github.com/DigitalDevices/octonet.git
synced 2023-10-10 13:36:52 +02:00
252 lines
7.7 KiB
Lua
252 lines
7.7 KiB
Lua
|
#!/usr/bin/lua
|
||
|
|
||
|
mc = {}
|
||
|
|
||
|
local DebugFlag = true
|
||
|
|
||
|
function mc.CheckSignal()
|
||
|
local tmp = io.open("/tmp/mc.signal")
|
||
|
if tmp then
|
||
|
tmp:close()
|
||
|
os.remove("/tmp/mc.signal")
|
||
|
return true
|
||
|
end
|
||
|
return nil
|
||
|
end
|
||
|
|
||
|
function mc:ReadSetupFile(filename)
|
||
|
local list = {}
|
||
|
local file = io.open(filename,"r")
|
||
|
print(filename,file)
|
||
|
if file then
|
||
|
local line = file:read()
|
||
|
if line then
|
||
|
if DebugFlag then print(line) end
|
||
|
line = string.gsub(line,'"','')
|
||
|
if line:match("TITLE,REQUEST,PIDS,LANPORTS") then
|
||
|
while true do
|
||
|
line = file:read()
|
||
|
if not line then break end
|
||
|
if DebugFlag then print(line) end
|
||
|
local title,request,pids,lanports = line:match('%"(.*)%",%"(.*)%",%"P(%a-[%d%:]-)%",%"L(%a-[%d%:]-)%"')
|
||
|
if not title then
|
||
|
title,request,pids = line:match('%"(.*)%",%"(.*)%",%"P(%a-[%d%:]-)%"')
|
||
|
end
|
||
|
if not title or not request or not pids then
|
||
|
break
|
||
|
end
|
||
|
if pids == "" then break end
|
||
|
|
||
|
pids = string.gsub(pids,":",",")
|
||
|
if lanports then
|
||
|
lanports = string.gsub(lanports,":",",")
|
||
|
if lanports == "" then lanports = nil end
|
||
|
if lanports == "all" then lanports = "1,2,3,4,5" end
|
||
|
end
|
||
|
local url
|
||
|
if request == "" or string.sub(request,1,1) ~= "?" then
|
||
|
url = "stream=%d?pids=" .. pids
|
||
|
else
|
||
|
url = request .. "&pids=" .. pids
|
||
|
end
|
||
|
table.insert(list,{ url = url, lanports = lanports })
|
||
|
end
|
||
|
elseif line:match("TITLE,REQUEST,PIDS,PROTO,IP,PORT,TTL,LANPORTS") then
|
||
|
while true do
|
||
|
line = file:read()
|
||
|
if not line then break end
|
||
|
if DebugFlag then print(line) end
|
||
|
local title,request,pids,proto,ip,port,ttl,lanports = line:match('%"(.*)%",%"(.*)%",%"P(%a-[%d%:]-)%",%"(%u%u%u)%",%"(%d*%.%d*%.%d*%.%d*)%",(%d*),(%d*),%"L(%a-[%d%:]-)%"')
|
||
|
if not title then
|
||
|
title,request,pids,proto,ip,port,ttl = line:match('%"(.*)%",%"(.*)%",%"P(%a-[%d%:]-)%",%"(%u%u%u)%",%"(%d*%.%d*%.%d*%.%d*)%",(%d*),(%d*)')
|
||
|
end
|
||
|
if not title or not request or not pids then
|
||
|
break
|
||
|
end
|
||
|
if pids == "" then break end
|
||
|
if proto ~= "UDP" and proto ~= "RTP" then break end
|
||
|
|
||
|
pids = string.gsub(pids,":",",")
|
||
|
if lanports then
|
||
|
lanports = string.gsub(lanports,":",",")
|
||
|
if lanports == "" then lanports = nil end
|
||
|
if lanports == "all" then lanports = "1,2,3,4,5" end
|
||
|
end
|
||
|
local url
|
||
|
if request == "" or string.sub(request,1,1) ~= "?" then
|
||
|
url = "stream=%d?pids=" .. pids
|
||
|
else
|
||
|
url = request .. "&pids=" .. pids
|
||
|
end
|
||
|
table.insert(list,{ url = url, proto = proto, ip = ip, port = port, ttl = ttl, lanports = lanports })
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
file:close()
|
||
|
end
|
||
|
return list
|
||
|
end
|
||
|
|
||
|
function mc:Setup(mclist,serverip,devid)
|
||
|
local streamid = 0
|
||
|
local port = 6670
|
||
|
local req = nil
|
||
|
local dest = 1
|
||
|
local SessionList = {}
|
||
|
local entry
|
||
|
|
||
|
for _,entry in ipairs(mclist) do
|
||
|
print("*************************************************************************")
|
||
|
req = entry.url
|
||
|
local rc = nil
|
||
|
local attributes = nil
|
||
|
local sdp = nil
|
||
|
local server = socket.tcp()
|
||
|
server:settimeout(2)
|
||
|
local cseq = 1
|
||
|
if server:connect(serverip,554) then
|
||
|
--local transport = string.format("RTP/AVP;multicast;port=%d-%d;ttl=5",port,port + 1)
|
||
|
local destip = string.format("239.%d.2.%d",devid,dest);
|
||
|
local destport = port;
|
||
|
local ttl = 5
|
||
|
if entry.ip then
|
||
|
destip = entry.ip
|
||
|
end
|
||
|
if entry.port then
|
||
|
destport = tonumber(entry.port)
|
||
|
end
|
||
|
if entry.ttl then
|
||
|
ttl = tonumber(entry.ttl)
|
||
|
end
|
||
|
local transport = nil
|
||
|
if entry.proto and entry.proto == "UDP" then
|
||
|
transport = string.format("UDP;multicast;destination=%s;port=%d;ttl=%d",destip,destport,ttl)
|
||
|
else
|
||
|
transport = string.format("RTP/AVP;multicast;destination=%s;port=%d-%d;ttl=%d",destip,destport,destport + 1,ttl)
|
||
|
end
|
||
|
|
||
|
-- port = port + 2
|
||
|
if string.match(req,"stream") then
|
||
|
if streamid > 0 then
|
||
|
req = string.format(req,streamid)
|
||
|
rtsp:SendRequest(server,serverip,"SETUP",req,cseq,transport)
|
||
|
rc,attributes,sdp = rtsp:ReadResponse(server)
|
||
|
cseq = cseq + 1
|
||
|
if rc == "200" then
|
||
|
session = string.match(attributes["SESSION"],"^(%w*);")
|
||
|
table.insert(SessionList,{ id = session, streamid = streamid, lanports = entry.lanports })
|
||
|
end
|
||
|
end
|
||
|
else
|
||
|
rtsp:SendRequest(server,serverip,"SETUP",req,cseq,transport)
|
||
|
rc,attributes,sdp = rtsp:ReadResponse(server)
|
||
|
cseq = cseq + 1
|
||
|
if rc == "200" then
|
||
|
streamid = tonumber(attributes["COM.SES.STREAMID"])
|
||
|
session = string.match(attributes["SESSION"],"^(%w*);")
|
||
|
table.insert(SessionList,{ id = session, streamid = streamid, lanports = entry.lanports })
|
||
|
end
|
||
|
end
|
||
|
server:close()
|
||
|
else
|
||
|
print("Connect?")
|
||
|
break
|
||
|
end
|
||
|
if rc ~= "200" then
|
||
|
break
|
||
|
end
|
||
|
dest = dest + 1
|
||
|
end
|
||
|
return SessionList
|
||
|
end
|
||
|
|
||
|
function mc:Play(SessionList,serverip)
|
||
|
if #SessionList > 0 then
|
||
|
local index,session
|
||
|
for index,session in ipairs(SessionList) do
|
||
|
print("*************************************************************************",index)
|
||
|
if session.lanports then
|
||
|
local server = socket.tcp()
|
||
|
server:settimeout(2)
|
||
|
if server:connect(serverip,554) then
|
||
|
local req = string.format("stream=%d",session.streamid)
|
||
|
rtsp:SendRequest(server,serverip,"PLAY",req,1,session.id, "switch="..session.lanports)
|
||
|
local rc,attributes,sdp = rtsp:ReadResponse(server)
|
||
|
server:close()
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function pKeepAlive(mc,SessionList,ip)
|
||
|
local index = 1
|
||
|
local server = socket.tcp()
|
||
|
server:settimeout(2)
|
||
|
local cseq = 1
|
||
|
print(SessionList,ip)
|
||
|
local status = 0
|
||
|
if server:connect(ip,554) then
|
||
|
while status do
|
||
|
socket.select(nil, nil, 3)
|
||
|
if mc.CheckSignal() then
|
||
|
status = 2
|
||
|
break
|
||
|
end
|
||
|
print("*************************************************",index,SessionList[index].id)
|
||
|
local err = rtsp:SendRequest(server,ip,"DESCRIBE",nil,cseq,SessionList[index].id)
|
||
|
if err then
|
||
|
print(err)
|
||
|
break
|
||
|
end
|
||
|
local rc,attributes,sdp = rtsp:ReadResponse(server)
|
||
|
if not rc or rc ~= "200" then
|
||
|
break
|
||
|
end
|
||
|
cseq = cseq + 1
|
||
|
index = index + 1
|
||
|
if index > #SessionList then
|
||
|
index = 1
|
||
|
end
|
||
|
collectgarbage()
|
||
|
end
|
||
|
server:close()
|
||
|
end
|
||
|
return status
|
||
|
end
|
||
|
|
||
|
function mc:KeepAlive(SessionList,serverip)
|
||
|
if #SessionList > 0 then
|
||
|
local rc,status = pcall(pKeepAlive,mc,SessionList,serverip)
|
||
|
if not rc then
|
||
|
print(status)
|
||
|
return 1
|
||
|
else
|
||
|
return status
|
||
|
end
|
||
|
end
|
||
|
return 0
|
||
|
end
|
||
|
|
||
|
function mc:TearDown(SessionList,serverip)
|
||
|
if #SessionList > 0 then
|
||
|
local index,session
|
||
|
for index,session in ipairs(SessionList) do
|
||
|
print("*************************************************************************",index)
|
||
|
local server = socket.tcp()
|
||
|
server:settimeout(2)
|
||
|
if server:connect(serverip,554) then
|
||
|
local req = string.format("stream=%d",session.streamid)
|
||
|
rtsp:SendRequest(server,serverip,"TEARDOWN",req,1,session.id)
|
||
|
local rc,attributes,sdp = rtsp:ReadResponse(server)
|
||
|
server:close()
|
||
|
if rc ~= "200" then
|
||
|
print("error",rc)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
return mc
|