1.修改原理
通过修改或者添加sdp中的字段实现控制码率的功能。
2. 修改代码示范
2.1 python
def setStartBitrate(codec,isVideoCodec:bool,sdp:str,bitrateKbps):
lines = sdp.split("\r\n")
rtpmapLineIndex = -1
sdpFormatUpdated = False
codecRtpMap = None
for i,line in enumerate(lines):
print(line)
m = re.search("^a=rtpmap:(\\d+) " + codec + "(/\\d+)+[\r]?$",line)
if m:
codecRtpMap=m.group(1)
rtpmapLineIndex=i
break
if codecRtpMap==None:
return sdp
print(f"Found " + codec + " rtpmap " + codecRtpMap + " at " + lines[rtpmapLineIndex])
for i,line in enumerate(lines):
m = re.search("^a=fmtp:" + codecRtpMap + " \\w+=\\d+.*[\r]?$",line)
if m:
print("Found " + codec + " " + lines[i])
if isVideoCodec:
lines[i] += "; " + "x-google-start-bitrate=" + bitrateKbps
else:
lines[i] += "; " + "maxaveragebitrate=" + (bitrateKbps * 1000)
sdpFormatUpdated = True
break
newSdpDescription:str=""
for i,line in enumerate(lines):
newSdpDescription+=(line+"\r\n")
if not sdpFormatUpdated and i==rtpmapLineIndex:
bitrateSet=""
if isVideoCodec:
bitrateSet="a=fmtp:" + codecRtpMap + " x-google-start-bitrate=" + str(bitrateKbps)
else:
bitrateSet = "a=fmtp:" + codecRtpMap + " maxaveragebitrate="+ str(bitrateKbps * 1000)
newSdpDescription+=(bitrateSet+"\r\n")
return newSdpDescription
2.2 JAVA代码
摘录webrtc的webrtcapp示例
private static final String VIDEO_CODEC_PARAM_START_BITRATE = "x-google-start-bitrate";
private static final String AUDIO_CODEC_PARAM_BITRATE = "maxaveragebitrate";
@SuppressWarnings("StringSplitter")
private static String setStartBitrate(
String codec, boolean isVideoCodec, String sdp, int bitrateKbps) {
String[] lines = sdp.split("\r\n");
int rtpmapLineIndex = -1;
boolean sdpFormatUpdated = false;
String codecRtpMap = null;
// Search for codec rtpmap in format
// a=rtpmap:<payload type> <encoding name>/<clock rate> [/<encoding parameters>]
String regex = "^a=rtpmap:(\\d+) " + codec + "(/\\d+)+[\r]?$";
Pattern codecPattern = Pattern.compile(regex);
for (int i = 0; i < lines.length; i++) {
Matcher codecMatcher = codecPattern.matcher(lines[i]);
if (codecMatcher.matches()) {
codecRtpMap = codecMatcher.group(1);
rtpmapLineIndex = i;
break;
}
}
if (codecRtpMap == null) {
Log.w(TAG, "No rtpmap for " + codec + " codec");
return sdp;
}
Log.d(TAG, "Found " + codec + " rtpmap " + codecRtpMap + " at " + lines[rtpmapLineIndex]);
// Check if a=fmtp string already exist in remote SDP for this codec and
// update it with new bitrate parameter.
regex = "^a=fmtp:" + codecRtpMap + " \\w+=\\d+.*[\r]?$";
codecPattern = Pattern.compile(regex);
for (int i = 0; i < lines.length; i++) {
Matcher codecMatcher = codecPattern.matcher(lines[i]);
if (codecMatcher.matches()) {
Log.d(TAG, "Found " + codec + " " + lines[i]);
if (isVideoCodec) {
lines[i] += "; " + VIDEO_CODEC_PARAM_START_BITRATE + "=" + bitrateKbps;
} else {
lines[i] += "; " + AUDIO_CODEC_PARAM_BITRATE + "=" + (bitrateKbps * 1000);
}
Log.d(TAG, "Update remote SDP line: " + lines[i]);
sdpFormatUpdated = true;
break;
}
}
StringBuilder newSdpDescription = new StringBuilder();
for (int i = 0; i < lines.length; i++) {
newSdpDescription.append(lines[i]).append("\r\n");
// Append new a=fmtp line if no such line exist for a codec.
if (!sdpFormatUpdated && i == rtpmapLineIndex) {
String bitrateSet;
if (isVideoCodec) {
bitrateSet =
"a=fmtp:" + codecRtpMap + " " + VIDEO_CODEC_PARAM_START_BITRATE + "=" + bitrateKbps;
} else {
bitrateSet = "a=fmtp:" + codecRtpMap + " " + AUDIO_CODEC_PARAM_BITRATE + "="
+ (bitrateKbps * 1000);
}
Log.d(TAG, "Add remote SDP line: " + bitrateSet);
newSdpDescription.append(bitrateSet).append("\r\n");
}
}
return newSdpDescription.toString();
}