1*3f982cf4SFabien Sanglard{ 2*3f982cf4SFabien Sanglard "$schema": "http://json-schema.org/draft-07/schema#", 3*3f982cf4SFabien Sanglard "$id": "https://something/streaming_schema.json", 4*3f982cf4SFabien Sanglard "definitions": { 5*3f982cf4SFabien Sanglard "ssrc": {"type": "integer", "minimum": 0, "maximum": 4294967295}, 6*3f982cf4SFabien Sanglard "delay": {"type": "integer", "minimum": 1, "maximum": 4000}, 7*3f982cf4SFabien Sanglard "resolution": { 8*3f982cf4SFabien Sanglard "width": {"type": "integer", "minimum": 320}, 9*3f982cf4SFabien Sanglard "height": {"type": "integer", "minimum": 240} 10*3f982cf4SFabien Sanglard }, 11*3f982cf4SFabien Sanglard "frame_rate": { 12*3f982cf4SFabien Sanglard "type": "string", 13*3f982cf4SFabien Sanglard "pattern": "[0-9]+(/[0-9]+)?", 14*3f982cf4SFabien Sanglard "examples": ["30", "30000/1001"] 15*3f982cf4SFabien Sanglard }, 16*3f982cf4SFabien Sanglard "dimensions": { 17*3f982cf4SFabien Sanglard "allOf": [ 18*3f982cf4SFabien Sanglard {"$ref": "#/definitions/resolution"}, 19*3f982cf4SFabien Sanglard {"properties": {"frameRate": {"$ref": "#/definitions/frame_rate"}}} 20*3f982cf4SFabien Sanglard ] 21*3f982cf4SFabien Sanglard }, 22*3f982cf4SFabien Sanglard "rtp_extensions": { 23*3f982cf4SFabien Sanglard "type": "array", 24*3f982cf4SFabien Sanglard "items": {"type": "string", "enum": ["adaptive_playout_delay"]} 25*3f982cf4SFabien Sanglard }, 26*3f982cf4SFabien Sanglard "stream": { 27*3f982cf4SFabien Sanglard "properties": { 28*3f982cf4SFabien Sanglard "index": {"type": "integer", "minimum": 0}, 29*3f982cf4SFabien Sanglard "type": {"type": "string", "enum": ["audio_source", "video_source"]}, 30*3f982cf4SFabien Sanglard "codecName": {"type": "string", "enum": ["aac", "opus", "h264", "vp8", "hevc", "vp9", "av1"]}, 31*3f982cf4SFabien Sanglard "codecParameter": {"type": "string"}, 32*3f982cf4SFabien Sanglard "rtpProfile": {"type": "string", "enum": ["cast"]}, 33*3f982cf4SFabien Sanglard "rtpPayloadType": {"type": "integer", "minimum": 96, "maximum": 127}, 34*3f982cf4SFabien Sanglard "ssrc": {"$ref": "#/definitions/ssrc"}, 35*3f982cf4SFabien Sanglard "targetDelay": {"$ref": "#/definitions/delay"}, 36*3f982cf4SFabien Sanglard "aesKey": {"type": "string", "pattern": "[0-9a-fA-F]{32}"}, 37*3f982cf4SFabien Sanglard "aesIvMask": {"type": "string", "pattern": "[0-9a-fA-F]{32}"}, 38*3f982cf4SFabien Sanglard "receiverRtcpEventLog": {"type": "boolean"}, 39*3f982cf4SFabien Sanglard "receiverRtcpDscp": {"type": "integer", "minimum": 0, "default": 46}, 40*3f982cf4SFabien Sanglard "rtpExtensions": {"$ref": "#/definitions/rtp_extensions"}, 41*3f982cf4SFabien Sanglard "timeBase": { 42*3f982cf4SFabien Sanglard "type": "string", 43*3f982cf4SFabien Sanglard "pattern": "1/[0-9]+", 44*3f982cf4SFabien Sanglard "default": "1/90000" 45*3f982cf4SFabien Sanglard } 46*3f982cf4SFabien Sanglard }, 47*3f982cf4SFabien Sanglard "required": [ 48*3f982cf4SFabien Sanglard "index", 49*3f982cf4SFabien Sanglard "type", 50*3f982cf4SFabien Sanglard "codecName", 51*3f982cf4SFabien Sanglard "rtpPayloadType", 52*3f982cf4SFabien Sanglard "ssrc", 53*3f982cf4SFabien Sanglard "aesKey", 54*3f982cf4SFabien Sanglard "aesIvMask", 55*3f982cf4SFabien Sanglard "timeBase" 56*3f982cf4SFabien Sanglard ] 57*3f982cf4SFabien Sanglard }, 58*3f982cf4SFabien Sanglard "audio_stream": { 59*3f982cf4SFabien Sanglard "allOf": [ 60*3f982cf4SFabien Sanglard {"$ref": "#/definitions/stream"}, 61*3f982cf4SFabien Sanglard { 62*3f982cf4SFabien Sanglard "properties": { 63*3f982cf4SFabien Sanglard "bitRate": {"type": "integer", "minimum": 0}, 64*3f982cf4SFabien Sanglard "channels": {"type": "integer", "minimum": 1} 65*3f982cf4SFabien Sanglard }, 66*3f982cf4SFabien Sanglard "required": ["bitRate", "channels"] 67*3f982cf4SFabien Sanglard } 68*3f982cf4SFabien Sanglard ] 69*3f982cf4SFabien Sanglard }, 70*3f982cf4SFabien Sanglard "video_stream": { 71*3f982cf4SFabien Sanglard "allOf": [ 72*3f982cf4SFabien Sanglard {"$ref": "#/definitions/stream"}, 73*3f982cf4SFabien Sanglard { 74*3f982cf4SFabien Sanglard "properties": { 75*3f982cf4SFabien Sanglard "maxFrameRate": {"$ref": "#/definitions/frame_rate"}, 76*3f982cf4SFabien Sanglard "maxBitRate": {"type": "integer", "minimum": 0}, 77*3f982cf4SFabien Sanglard "resolutions": { 78*3f982cf4SFabien Sanglard "type": "array", 79*3f982cf4SFabien Sanglard "items": {"$ref": "#/definitions/resolution"} 80*3f982cf4SFabien Sanglard }, 81*3f982cf4SFabien Sanglard "errorRecoveryMode": { 82*3f982cf4SFabien Sanglard "type": "string", 83*3f982cf4SFabien Sanglard "enum": ["castv2", "intra_mb_refresh"], 84*3f982cf4SFabien Sanglard "default": "castv2" 85*3f982cf4SFabien Sanglard } 86*3f982cf4SFabien Sanglard }, 87*3f982cf4SFabien Sanglard "required": ["maxFrameRate", "maxBitRate", "resolutions"] 88*3f982cf4SFabien Sanglard } 89*3f982cf4SFabien Sanglard ] 90*3f982cf4SFabien Sanglard }, 91*3f982cf4SFabien Sanglard "offer": { 92*3f982cf4SFabien Sanglard "properties": { 93*3f982cf4SFabien Sanglard "supportedStreams": { 94*3f982cf4SFabien Sanglard "type": "array", 95*3f982cf4SFabien Sanglard "items": {"$ref": "#/definitions/stream"} 96*3f982cf4SFabien Sanglard }, 97*3f982cf4SFabien Sanglard "castMode": {"type": "string", "enum": ["mirroring", "remoting"]}, 98*3f982cf4SFabien Sanglard "receiverStatus": {"type": "boolean"} 99*3f982cf4SFabien Sanglard } 100*3f982cf4SFabien Sanglard }, 101*3f982cf4SFabien Sanglard "audio_constraints": { 102*3f982cf4SFabien Sanglard "properties": { 103*3f982cf4SFabien Sanglard "maxSampleRate": { 104*3f982cf4SFabien Sanglard "type": "integer", 105*3f982cf4SFabien Sanglard "minimum": 16000, 106*3f982cf4SFabien Sanglard "default": 48000, 107*3f982cf4SFabien Sanglard "maximum": 96000 108*3f982cf4SFabien Sanglard }, 109*3f982cf4SFabien Sanglard "maxChannels": {"type": "integer", "minimum": 1, "default": 2}, 110*3f982cf4SFabien Sanglard "minBitRate": {"type": "integer", "minimum": 32000, "maximum": 320000}, 111*3f982cf4SFabien Sanglard "maxBitRate": {"type": "integer", "minimum": 32000, "maximum": 320000}, 112*3f982cf4SFabien Sanglard "maxDelay": {"$ref": "#/definitions/delay"} 113*3f982cf4SFabien Sanglard }, 114*3f982cf4SFabien Sanglard "required": ["maxSampleRate", "maxChannels", "maxBitRate"] 115*3f982cf4SFabien Sanglard }, 116*3f982cf4SFabien Sanglard "video_constraints": { 117*3f982cf4SFabien Sanglard "properties": { 118*3f982cf4SFabien Sanglard "maxPixelsPerSecond": {"type": "number", "minimum": 0}, 119*3f982cf4SFabien Sanglard "minResolution": {"$ref": "#/definitions/resolution"}, 120*3f982cf4SFabien Sanglard "maxDimensions": {"$ref": "#/definitions/dimensions"}, 121*3f982cf4SFabien Sanglard "minBitRate": {"type": "integer", "minimum": 300000}, 122*3f982cf4SFabien Sanglard "maxBitRate": {"type": "integer", "minimum": 300000}, 123*3f982cf4SFabien Sanglard "maxDelay": {"$ref": "#/definitions/delay"} 124*3f982cf4SFabien Sanglard }, 125*3f982cf4SFabien Sanglard "required": ["maxDimensions", "maxBitRate"] 126*3f982cf4SFabien Sanglard }, 127*3f982cf4SFabien Sanglard "constraints": { 128*3f982cf4SFabien Sanglard "properties": { 129*3f982cf4SFabien Sanglard "audio": {"$ref": "#/definitions/audio_constraints"}, 130*3f982cf4SFabien Sanglard "video": {"$ref": "#/definitions/video_constraints"} 131*3f982cf4SFabien Sanglard }, 132*3f982cf4SFabien Sanglard "required": ["audio", "video"] 133*3f982cf4SFabien Sanglard }, 134*3f982cf4SFabien Sanglard "display": { 135*3f982cf4SFabien Sanglard "$id": "#display", 136*3f982cf4SFabien Sanglard "properties": { 137*3f982cf4SFabien Sanglard "dimensions": {"$ref": "#/definitions/dimensions"}, 138*3f982cf4SFabien Sanglard "aspectRatio": {"type": "string", "pattern": "[0-9]+:[0-9]+"}, 139*3f982cf4SFabien Sanglard "scaling": {"type": "string", "enum": ["sender", "receiver"]} 140*3f982cf4SFabien Sanglard }, 141*3f982cf4SFabien Sanglard "required": [] 142*3f982cf4SFabien Sanglard }, 143*3f982cf4SFabien Sanglard "error": { 144*3f982cf4SFabien Sanglard "properties": { 145*3f982cf4SFabien Sanglard "code": {"type": "integer"}, 146*3f982cf4SFabien Sanglard "description": {"type": "string"} 147*3f982cf4SFabien Sanglard }, 148*3f982cf4SFabien Sanglard "required": ["code", "description"] 149*3f982cf4SFabien Sanglard }, 150*3f982cf4SFabien Sanglard "answer": { 151*3f982cf4SFabien Sanglard "type": "object", 152*3f982cf4SFabien Sanglard "properties": { 153*3f982cf4SFabien Sanglard "udpPort": {"type": "integer", "minimum": 1, "maximum": 65535}, 154*3f982cf4SFabien Sanglard "sendIndexes": { 155*3f982cf4SFabien Sanglard "type": "array", 156*3f982cf4SFabien Sanglard "items": {"type": "integer", "minimum": 0} 157*3f982cf4SFabien Sanglard }, 158*3f982cf4SFabien Sanglard "ssrcs": {"type": "array", "items": {"$ref": "#/definitions/ssrc"}}, 159*3f982cf4SFabien Sanglard "constraints": {"$ref": "#/definitions/constraints"}, 160*3f982cf4SFabien Sanglard "display": {"$ref": "#/definitions/display"}, 161*3f982cf4SFabien Sanglard "receiverRtcpEventLog": { 162*3f982cf4SFabien Sanglard "type": "array", 163*3f982cf4SFabien Sanglard "items": {"type": "integer", "minimum": 0} 164*3f982cf4SFabien Sanglard }, 165*3f982cf4SFabien Sanglard "receiverRtcpDscp": { 166*3f982cf4SFabien Sanglard "type": "array", 167*3f982cf4SFabien Sanglard "items": {"type": "integer", "minimum": 0} 168*3f982cf4SFabien Sanglard }, 169*3f982cf4SFabien Sanglard "rtpExtensions": {"$ref": "#/definitions/rtp_extensions"} 170*3f982cf4SFabien Sanglard }, 171*3f982cf4SFabien Sanglard "required": ["udpPort", "sendIndexes", "ssrcs"] 172*3f982cf4SFabien Sanglard }, 173*3f982cf4SFabien Sanglard "capabilities": { 174*3f982cf4SFabien Sanglard "$id": "#capabilities", 175*3f982cf4SFabien Sanglard "type": "object", 176*3f982cf4SFabien Sanglard "properties": { 177*3f982cf4SFabien Sanglard "mediaCaps": { 178*3f982cf4SFabien Sanglard "type": "array", 179*3f982cf4SFabien Sanglard "items": { 180*3f982cf4SFabien Sanglard "type": "string", 181*3f982cf4SFabien Sanglard "enum": [ 182*3f982cf4SFabien Sanglard "audio", 183*3f982cf4SFabien Sanglard "aac", 184*3f982cf4SFabien Sanglard "opus", 185*3f982cf4SFabien Sanglard "video", 186*3f982cf4SFabien Sanglard "4k", 187*3f982cf4SFabien Sanglard "h264", 188*3f982cf4SFabien Sanglard "vp8", 189*3f982cf4SFabien Sanglard "hevc", 190*3f982cf4SFabien Sanglard "vp9" 191*3f982cf4SFabien Sanglard ] 192*3f982cf4SFabien Sanglard } 193*3f982cf4SFabien Sanglard }, 194*3f982cf4SFabien Sanglard "remoting": {"type": "integer"} 195*3f982cf4SFabien Sanglard }, 196*3f982cf4SFabien Sanglard "required": ["mediaCaps"] 197*3f982cf4SFabien Sanglard } 198*3f982cf4SFabien Sanglard }, 199*3f982cf4SFabien Sanglard "type": "object", 200*3f982cf4SFabien Sanglard "properties": { 201*3f982cf4SFabien Sanglard "offer": {"$ref": "#/definitions/offer"}, 202*3f982cf4SFabien Sanglard "answer": {"$ref": "#/definitions/answer"}, 203*3f982cf4SFabien Sanglard "capabilities": {"$ref": "#/definitions/capabilities"}, 204*3f982cf4SFabien Sanglard "error": {"$ref": "#/definitions/error"}, 205*3f982cf4SFabien Sanglard "result": {"type": "string", "enum": ["ok", "error"]}, 206*3f982cf4SFabien Sanglard "seqNum": {"type": "integer", "minimum": 0}, 207*3f982cf4SFabien Sanglard "sessionId": {"type": "integer"}, 208*3f982cf4SFabien Sanglard "type": { 209*3f982cf4SFabien Sanglard "type": "string", 210*3f982cf4SFabien Sanglard "enum": [ 211*3f982cf4SFabien Sanglard "OFFER", 212*3f982cf4SFabien Sanglard "ANSWER", 213*3f982cf4SFabien Sanglard "GET_STATUS", 214*3f982cf4SFabien Sanglard "STATUS_RESPONSE", 215*3f982cf4SFabien Sanglard "GET_CAPABILITIES", 216*3f982cf4SFabien Sanglard "CAPABILITIES_RESPONSE", 217*3f982cf4SFabien Sanglard "RPC" 218*3f982cf4SFabien Sanglard ] 219*3f982cf4SFabien Sanglard } 220*3f982cf4SFabien Sanglard }, 221*3f982cf4SFabien Sanglard "required": ["type"], 222*3f982cf4SFabien Sanglard "allOf": [ 223*3f982cf4SFabien Sanglard { 224*3f982cf4SFabien Sanglard "if": { 225*3f982cf4SFabien Sanglard "properties": { 226*3f982cf4SFabien Sanglard "type": { 227*3f982cf4SFabien Sanglard "enum": ["ANSWER", "CAPABILITIES_RESPONSE", "STATUS_RESPONSE"] 228*3f982cf4SFabien Sanglard } 229*3f982cf4SFabien Sanglard } 230*3f982cf4SFabien Sanglard }, 231*3f982cf4SFabien Sanglard "then": {"required": ["result"]} 232*3f982cf4SFabien Sanglard }, 233*3f982cf4SFabien Sanglard { 234*3f982cf4SFabien Sanglard "if": { 235*3f982cf4SFabien Sanglard "properties": { 236*3f982cf4SFabien Sanglard "type": { 237*3f982cf4SFabien Sanglard "enum": [ 238*3f982cf4SFabien Sanglard "OFFER", 239*3f982cf4SFabien Sanglard "ANSWER", 240*3f982cf4SFabien Sanglard "GET_CAPABILITIES", 241*3f982cf4SFabien Sanglard "CAPABILITIES_RESPONSE", 242*3f982cf4SFabien Sanglard "GET_STATUS", 243*3f982cf4SFabien Sanglard "STATUS_RESPONSE" 244*3f982cf4SFabien Sanglard ] 245*3f982cf4SFabien Sanglard } 246*3f982cf4SFabien Sanglard } 247*3f982cf4SFabien Sanglard }, 248*3f982cf4SFabien Sanglard "then": {"required": ["seqNum"]} 249*3f982cf4SFabien Sanglard }, 250*3f982cf4SFabien Sanglard { 251*3f982cf4SFabien Sanglard "if": {"properties": {"type": {"const": "OFFER"}}}, 252*3f982cf4SFabien Sanglard "then": {"required": ["offer"]} 253*3f982cf4SFabien Sanglard }, 254*3f982cf4SFabien Sanglard { 255*3f982cf4SFabien Sanglard "if": { 256*3f982cf4SFabien Sanglard "properties": {"type": {"const": "ANSWER"}, "result": {"const": "ok"}} 257*3f982cf4SFabien Sanglard }, 258*3f982cf4SFabien Sanglard "then": {"required": ["answer"]} 259*3f982cf4SFabien Sanglard }, 260*3f982cf4SFabien Sanglard { 261*3f982cf4SFabien Sanglard "if": { 262*3f982cf4SFabien Sanglard "properties": { 263*3f982cf4SFabien Sanglard "type": {"const": "CAPABILITIES_RESPONSE"}, 264*3f982cf4SFabien Sanglard "result": {"const": "ok"} 265*3f982cf4SFabien Sanglard } 266*3f982cf4SFabien Sanglard }, 267*3f982cf4SFabien Sanglard "then": {"required": ["capabilities"]} 268*3f982cf4SFabien Sanglard }, 269*3f982cf4SFabien Sanglard { 270*3f982cf4SFabien Sanglard "if": { 271*3f982cf4SFabien Sanglard "properties": {"type": {"const": "RPC"}, "result": {"const": "ok"}} 272*3f982cf4SFabien Sanglard }, 273*3f982cf4SFabien Sanglard "then": {"required": ["rpc"]} 274*3f982cf4SFabien Sanglard } 275*3f982cf4SFabien Sanglard ] 276*3f982cf4SFabien Sanglard} 277