mirror of
https://github.com/bluenviron/mediamtx.git
synced 2025-12-20 02:00:05 -08:00
207 lines
5.3 KiB
JavaScript
207 lines
5.3 KiB
JavaScript
// Message Types for MQTT Communication
|
|
|
|
/**
|
|
* Signaling Message Types
|
|
*/
|
|
const SignalingType = {
|
|
REQUEST: 'request', // Initial request from client
|
|
OFFER: 'offer', // SDP Offer from camera/NVR
|
|
ANSWER: 'answer', // SDP Answer from client
|
|
DENY: 'deny', // Connection denied (max clients reached)
|
|
CCU: 'ccu', // Concurrent user count update
|
|
ICE_CANDIDATE: 'ice-candidate' // ICE candidate exchange
|
|
};
|
|
|
|
/**
|
|
* Data Channel Commands
|
|
*/
|
|
const DataChannelCommand = {
|
|
STREAM: 'Stream',
|
|
ONVIF_STATUS: 'OnvifStatus'
|
|
};
|
|
|
|
/**
|
|
* Result Codes
|
|
*/
|
|
const ResultCode = {
|
|
SUCCESS: 100,
|
|
FAIL: 103,
|
|
STREAM_SUCCESS: 0
|
|
};
|
|
|
|
/**
|
|
* Create Signaling Request Message
|
|
* @param {string} serial - Camera/NVR serial number
|
|
* @param {string} clientId - Unique client identifier
|
|
* @returns {object} - Signaling request message
|
|
*/
|
|
function createSignalingRequest(serial, clientId) {
|
|
return {
|
|
Method: 'ACT',
|
|
MessageType: 'Signaling',
|
|
Serial: serial,
|
|
Data: {
|
|
Type: SignalingType.REQUEST,
|
|
ClientId: clientId
|
|
},
|
|
Timestamp: Math.floor(Date.now() / 1000)
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Create SDP Answer Message
|
|
* @param {string} serial - Camera/NVR serial number
|
|
* @param {string} clientId - Unique client identifier
|
|
* @param {string} sdp - SDP Answer string
|
|
* @returns {object} - SDP Answer message
|
|
*/
|
|
function createAnswerMessage(serial, clientId, sdp) {
|
|
return {
|
|
Method: 'ACT',
|
|
MessageType: 'Signaling',
|
|
Serial: serial,
|
|
Data: {
|
|
Type: SignalingType.ANSWER,
|
|
Sdp: sdp,
|
|
ClientId: clientId
|
|
},
|
|
Timestamp: Math.floor(Date.now() / 1000),
|
|
Result: {
|
|
Ret: ResultCode.SUCCESS,
|
|
Message: 'Success'
|
|
}
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Create ICE Candidate Message
|
|
* @param {string} serial - Camera/NVR serial number
|
|
* @param {string} clientId - Unique client identifier
|
|
* @param {RTCIceCandidate} candidate - ICE candidate
|
|
* @returns {object} - ICE candidate message
|
|
*/
|
|
function createIceCandidateMessage(serial, clientId, candidate) {
|
|
return {
|
|
Method: 'ACT',
|
|
MessageType: 'Signaling',
|
|
Serial: serial,
|
|
Data: {
|
|
Type: SignalingType.ICE_CANDIDATE,
|
|
ClientId: clientId,
|
|
Candidate: {
|
|
candidate: candidate.candidate,
|
|
sdpMid: candidate.sdpMid,
|
|
sdpMLineIndex: candidate.sdpMLineIndex
|
|
}
|
|
},
|
|
Timestamp: Math.floor(Date.now() / 1000)
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Create Credential Message
|
|
* @param {string} serial - Camera/NVR serial number
|
|
* @param {string} username - Camera username
|
|
* @param {string} password - Camera password
|
|
* @param {string} ip - Camera IP address (optional, will be discovered via ONVIF if not provided)
|
|
* @returns {object} - Credential message
|
|
*/
|
|
function createCredentialMessage(serial, username, password, ip = '') {
|
|
const data = {
|
|
Username: username,
|
|
Password: password
|
|
};
|
|
|
|
// Only include IP if provided
|
|
if (ip) {
|
|
data.IP = ip;
|
|
}
|
|
|
|
return {
|
|
Method: 'ACT',
|
|
MessageType: 'Credential',
|
|
Serial: serial,
|
|
Data: data,
|
|
Timestamp: Math.floor(Date.now() / 1000)
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Create Stream Request for Data Channel
|
|
* @param {string} nvrSerial - NVR serial number
|
|
* @param {number} channelMask - 64-bit bitmask for channel enable (bit0=CH1...bit15=CH16)
|
|
* @param {number} resolutionMask - 64-bit bitmask for stream type (0=sub, 1=main)
|
|
* @returns {object} - Stream request message
|
|
*/
|
|
function createStreamRequest(nvrSerial, channelMask, resolutionMask) {
|
|
return {
|
|
Id: nvrSerial,
|
|
Command: DataChannelCommand.STREAM,
|
|
Type: 'Request',
|
|
Content: {
|
|
ChannelMask: channelMask,
|
|
ResolutionMask: resolutionMask
|
|
}
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Create ONVIF Status Request for Data Channel
|
|
* @param {string} nvrSerial - NVR serial number
|
|
* @returns {object} - ONVIF status request message
|
|
*/
|
|
function createOnvifStatusRequest(nvrSerial) {
|
|
return {
|
|
Id: nvrSerial,
|
|
Command: DataChannelCommand.ONVIF_STATUS,
|
|
Type: 'Request',
|
|
Content: {}
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Parse Signaling Response
|
|
* @param {object} message - Received message
|
|
* @returns {object} - Parsed response with type and data
|
|
*/
|
|
function parseSignalingResponse(message) {
|
|
const result = {
|
|
success: false,
|
|
type: null,
|
|
data: null,
|
|
error: null
|
|
};
|
|
|
|
try {
|
|
if (message.Result && message.Result.Ret !== ResultCode.SUCCESS) {
|
|
result.error = message.Result.Message || 'Unknown error';
|
|
return result;
|
|
}
|
|
|
|
if (message.Data) {
|
|
result.type = message.Data.Type;
|
|
result.data = message.Data;
|
|
result.success = true;
|
|
}
|
|
} catch (e) {
|
|
result.error = e.message;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
// Export for module usage
|
|
if (typeof module !== 'undefined' && module.exports) {
|
|
module.exports = {
|
|
SignalingType,
|
|
DataChannelCommand,
|
|
ResultCode,
|
|
createSignalingRequest,
|
|
createAnswerMessage,
|
|
createIceCandidateMessage,
|
|
createCredentialMessage,
|
|
createStreamRequest,
|
|
createOnvifStatusRequest,
|
|
parseSignalingResponse
|
|
};
|
|
}
|