TongjiAI Media Service Instruction

TongjiAI Media Service Instruction

Realtime Streaming

1. Request streaming from devices.

Devices are designed to be accesed via socket.io. By default a device gets itself registered at the official socket.io server once it is connected to the internet, either via wirelss LANs(aka Wifi) or 4G/5G cellular networks. Clients who are willing to request the realtime video streaming should connect themselves to the socket.io server and join the same room with the target devices, which is followed by the steps below:

a) Connect to socket.io server with an arbitary socket.io client implementation (listed here).
b) Emit a “find” event to join the same room with the target device.

1
2
3
const socket = io("https://server-domain.com");
const device = "tj01";
socket.emit("find", device);

c) Write the socket.io event handler for “create” and “join” event. Emit the “auth” and “heartbeatping” events in both handlers.

1
2
3
4
5
6
7
8
socket.on("create", ()=> {
socket.emit("auth");
socket.emit("heartbeatping");
});
socket.on("join", ()=> {
socket.emit("auth");
socket.emit("heartbeatping");
});

d) Write an event handler for “heartbeatpong” event to keep the streaming on.

1
2
3
4
5
6
7
8
9
let heartbeat_timer;
socketio.on("heartbeatpong", () => {
if (heartbeat_timer) {
clearTimeout(heartbeat_timer);
}
heartbeat_timer = setTimeout(() => {
socketio.emit("heartbeatping");
}, 10000);
});

e) Write an event handler for “bridge” event which carries the argument of the streaming path.

1
2
3
4
5
6
7
socketio.on("bridge", async (pathid) => {
setTimeout(() => {
setRemoteStream(
`https://live.tongjiai.cn/channel/${pathid}/index.m3u8`
);
}, 3000);
});

2. Read the realtime streaming.

If everything went fine in previous section, we have fetched the path of the realtime streaming which can be read or embedded into html tags. There are several protocols we provide for accessing and reading the streaming, including RTSP, HLS, RTMP and WebRTC, all of which support SSL/TLS encryption.
Generally all protocols share the same hosts and paths as well as different schemes and ports. As mentioned in the code block of part e) of the previous section, the URI of the streaming are in the form of

1
2
`rtsp://live.tongjiai.cn/channel/${path}`
`https://live.tongjiai.cn/channel/${path}/index.m3u8`

It is considered reliable to embed the HLS streaming uri (latter above) in an <video /> tag or via a third party video library like hls.js while an RTSP uri usually needs some other tricks to be played in modern browsers (Firefox/Chrome/Edge/Safari). If you are not limited by web platforms, say it like you are developing an mobile app, you can always call the native or external media player(or their API) to make use of either uri as you like.

Video Records

1. Request video clip lists.

Video clips are recorded as long as devices are powered on. The clips are stored in the SD card of the device and synced to the cloud storage once the device is connected online. Clients that have joined the room in the socket.io server (see part b of the previous section.) are capable of fetching the synced clip lists via emitting the “getRecList” event and writing the “recList” event handler.

1
2
3
4
socket.emit("getRecList");
socketio.on("recList", (list) => {
setRecList(list);
});

The argument of the “recList” event handler is expected to be the list of video clip names of the device which you are in the socket.io room with.

2. Get video clips.

Video clips listed in the payload of “recList” event handler are to be accessed and downloaed via the presigned link generated by requesting “POST” to this API. The headers and body of the “POST” request is expected to follow the json form of:

1
2
3
4
5
6
7
8
const headers = {
Content-Type: "application/json",
token: accessToken
};
const body = {
device: "tj01",
recFile: "2022-08-01T12:03:01.mp4"
}

The accessToken in the code block is acquired by requesting “POST” to the token API. The payload form is:

1
2
3
4
5
6
7
const headers = {
Content-Type: "application/json"
};
const body = {
name: "username",
password: "password"
}

The username and password above are to be replaced with your own registry information. If you have posted the right authentication, the return code would carry the payload that containing the access token which you should attach to headers of presigned url requesting.

1
2
3
4
5
{
message: "Authenticated.",
success: true,
token: "accessToken"
}

And the successful request to the getPresignedUrl API return the payload of:

1
2
3
4
5
{
message: "Presigned URL generated.",
success: true,
presignedUrl: "temporaryClipDownloadLink"
}