Network Testing
Feature Overview
ZEGO provides network testing functionality that can detect uplink and downlink network speeds before users perform stream publishing/playing, to determine what bitrate of audio and video streams are suitable for publishing/playing under the current network environment.
When the uplink testing result shows poor network quality, it is recommended that users switch to a better network or lower the publishing bitrate by reducing resolution or frame rate to ensure normal stream publishing.
When the following situations occur in developer business, ZEGO recommends using the SDK's network testing feature:
- Network quality assessment is required in call scenarios.
- Pre-class network detection is required in education scenarios.
- Network connection speed testing is required in live streaming scenarios.
The basic principle of network testing is shown in the following diagram:

Example Source Code Download
Please refer to Download Example Source Code to obtain the source code.
For related source code, please view files in the "src/Examples/Others/NetworkDetection" directory.
Prerequisites
Before implementing the network testing feature, please ensure:
- You have created a project in the ZEGOCLOUD Console and applied for a valid AppID and Server address. For details, please refer to Console - Project Information.
- You have integrated ZEGO Express SDK in your project and implemented basic audio and video stream publishing and playing functions. For details, please refer to Quick Start - Integration and Quick Start - Implementation.
Usage Steps
Implementation Operations
- Create a ZegoExpressEngine instance object zg.
- Call the loginRoom interface to log in to a room for testing the network.
- Call the createZegoStream interface, set the expected video quality parameters and bitrate that the network should meet in the
qualityparameter, and create a camera-related ZegoLocalStream instance object. - Call the startPublishingStream interface to perform stream publishing, and get the uplink network quality
stats.video.videoQualityby listening to the publishQualityUpdate event. - Call the startPlayingStream interface to perform stream playing, and get the downlink network quality
stats.video.videoQualityby listening to the playQualityUpdate event. - The entire network testing process can last about 15 seconds (at least 7 seconds). Finally, take the average network quality based on the number of network quality callbacks (callbacks start from the 6th second after stream publishing/playing begins, and callback once every 3 seconds) to roughly determine the uplink and downlink network conditions. After the test ends, you can choose whether to exit the room and destroy the media stream.
Example Code
/**
* Use ZegoExpressEngine to detect network quality.
* @param {ZegoExpressEngine} zg -- ZegoExpressEngine instance
* @param {number} seconds -- Detection duration, at least 8 seconds
* @returns Promise Asynchronously returns detection results
*/
function detectNetworkQuality(zg, seconds = 10) {
return new Promise(async (resolve, reject) => {
if (!zg) {
reject()
return
}
let isLogin = false;
let localStream = null
let testStreamID = "for_testing_" + Date.now()
let uplinkList = []
let downlinkList = []
function onDetectionEnd(error) {
// Detection ends, unsubscribe from events, destroy stream, logout from room
zg.off("publishQualityUpdate", eventHandler.publishQualityUpdate)
zg.off("playQualityUpdate", eventHandler.playQualityUpdate)
zg.off("publisherStateUpdate", eventHandler.publisherStateUpdate)
zg.off("playerStateUpdate", eventHandler.playerStateUpdate)
if (localStream) {
zg.destroyStream(localStream)
localStream = null
}
zg.logoutRoom()
isLogin = false
if (error) {
reject(error)
}
// Calculate uplink and downlink network averages
const downlink = downlinkList.length ? (downlinkList.reduce((result, item) => (result + item), 0) / downlinkList.length) : -1
const uplink = uplinkList.length ? (uplinkList.reduce((result, item) => (result + item), 0) / uplinkList.length) : -1
resolve({
downlink: Math.round(downlink),
uplink: Math.round(uplink)
})
}
const eventHandler = {
playQualityUpdate: (streamID, stats) => {
// Get downlink network quality stats.video.videoQuality by listening to the playQualityUpdate event
const quality = stats.video.videoQuality
if (quality > -1) {
downlinkList.push(quality)
}
},
publishQualityUpdate: (streamID, stats) => {
// Get uplink network quality stats.video.videoQuality by listening to the publishQualityUpdate event
const quality = stats.video.videoQuality
if (quality > -1) {
uplinkList.push(quality)
}
},
publisherStateUpdate: ({ streamID, state }) => {
if (streamID === testStreamID && state === "PUBLISHING") {
// Call startPlayingStream to perform stream playing
zg.startPlayingStream(streamID)
}
},
playerStateUpdate: async ({ streamID, state }) => {
if (streamID === testStreamID && state === "PLAYING") {
setTimeout(() => {
onDetectionEnd()
}, seconds * 1e3)
}
}
}
zg.on("publishQualityUpdate", eventHandler.publishQualityUpdate)
zg.on("playQualityUpdate", eventHandler.playQualityUpdate)
zg.on("publisherStateUpdate", eventHandler.publisherStateUpdate)
zg.on("playerStateUpdate", eventHandler.playerStateUpdate)
// Call the loginRoom interface to log in to a room for testing the network.
isLogin = await zg.loginRoom(roomID, token, {
userID
}).catch(error => {
let errMsg = error.msg
if (error.code === 1102016) {
errMsg = "Token error"
}
onDetectionEnd(errMsg)
throw error
})
if (!isLogin) {
onDetectionEnd(errMsg)
}
// Call the createZegoStream interface to create a camera-related media stream object, and set the expected video quality parameters and bitrate that the network should meet in the createZegoStream interface parameters
localStream = await zg.createZegoStream({
camera: {
video: {
quality: 3
}
}
}).catch(error => {
onDetectionEnd(errMsg)
throw error
})
// Call startPublishingStream to perform stream publishing
zg.startPublishingStream(testStreamID, localStream)
})
}
// Create ZegoExpressEngine instance object zg
const zg = new ZegoExpressEngine(appID, server)
// Start detecting network quality
detectNetworkQuality(zg, 15).then(({ uplink, downlink }) => {
// Get uplink and downlink network quality uplink and downlink, and display detection results through UI
}).catch(err => {
// Error during detection process, possibly login failure or stream creation failure, prompt detection failure through UI
})Result Analysis
Through the above steps, obtain the average uplink network quality and average downlink network quality. The enum value meanings of network quality videoQuality are as follows:
| Value | Meaning |
| -1 | Network status is unknown, indicating that the current zg instance has not established an uplink/downlink connection. |
| 0 | Network status is excellent. |
| 1 | Network status is good. |
| 2 | Network status is fair. |
| 3 | Network status is poor. |
| 4 | Network status is very poor. |
