octonet/octoserve/var/mcsetup/mc.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