Closed robin2099 closed 2 years ago
Take a screenshot. What is a "blob of paste"? Is it screen distortion or low bitrate blurring? Is it blurry playback or some other phenomenon?
TRANS_BY_GPT3
@robin2099 Can you conveniently provide the py script for this test?
TRANS_BY_GPT3
@xiaozhihong This is the situation, I don't know if it can be defined as screen flickering.
TRANS_BY_GPT3
@xiaozhihong client_srs.py.zip Python script, using local docker srs4 for testing
TRANS_BY_GPT3
@xiaozhihong client_srs.py.zip python script, using local docker srs4 for testing
@robin2099 I checked this script and it's really good and useful. I tested it and the performance is consistent with yours. This is not screen flickering, it's caused by low bitrate. How can I control the bitrate with the python av library? I tried changing the options to...
options = {"framerate": "30", "video_size": "1280x720", "bitrate": "8000000"}
However, it didn't work. If you know how to modify the encoding parameters and bitrate of libx264 in python, please test it and share it with us.
TRANS_BY_GPT3
@xiaozhihong Okay, thank you for helping to locate the problem 🙏
TRANS_BY_GPT3
@xiaozhihong Okay, thanks for helping to locate the problem. Pray
Have you solved the problem? I am also trying to use aiortc for streaming, referring to your solution.
TRANS_BY_GPT3
@CodeIsWorld Not yet, I have tried many methods but still couldn't achieve a clear picture by modifying the bitrate.
TRANS_BY_GPT3
Hello, do you have an example of using aiortc to stream and then displaying it with opencv? I tried to stream using aiortc, but it keeps failing o(╥﹏╥)o.
TRANS_BY_GPT3
@CodeIsWorld I haven't found a way yet. I've tried many methods but still couldn't achieve a clear picture by modifying the bitrate.
I fixed this issue based on the answer to this problem https://github.com/aiortc/aiortc/issues/170. The bitrate is calculated by the server based on the available bandwidth and sent to the client. It seems that there is a mismatch in the negotiation between SRS and aiortc, resulting in a low resolution set on the client side. I modified the source code of aiortc for RTP sending in aiortc/src/aiortc/rtcrtpsender.py. async def _next_encoded_frame(self, codec: RTCRtpCodecParameters):
frame = await self.__track.recv()
if self.__encoder is None:
self.__encoder = get_encoder(codec)
force_keyframe = self.__force_keyframe
self.__force_keyframe = False
return await self.__loop.run_in_executor(
None, self.__encoder.encode, frame, force_keyframe
)
The bitrate is mainly set in self.encoder. The decoder type is set based on the codec type in the file src/aiortc/codecs/init__.py, line 144. I noticed that my encoder type is H264Encoder(). The most crucial encoding function is in the file src/aiortc/codecs/h264.py, line 268, in the function _encode_frame(). The minimum bitrate is set at line 17. DEFAULT_BITRATE = 1000000 # 1 Mbps MIN_BITRATE = 500000 # 500 kbps MAX_BITRATE = 3000000 # 3 Mbps
MAX_FRAME_RATE = 30 PACKET_MAX = 1300 If the bitrate sent by the server is lower than this minimum value, it will use this minimum value. So, directly increase the MIN_BITRATE minimum value, then compile the source code and install it (remember to first uninstall the previously installed aiortc with pip), sudo python3 setup.py install, and then run the client's source code to see if the bitrate can be increased.
*****update*
After testing, there is still a problem. The line 282 if self.codec is None:
is only None for the first time, and then it keeps using self.codec
, causing issues with the bitrate. So, my solution is to force self.codec = None
before line 282, and then set self.target_bitrate
. Each frame that comes in will create a new encoder, ultimately resolving the issue as follows.
def _encode_frame( self, frame: av.VideoFrame, force_keyframe: bool ) -> Iterator[bytes]: if self.codec and ( frame.width != self.codec.width or frame.height != self.codec.height
we only adjust bitrate if it changes by over 10%
or abs(self.target_bitrate - self.codec.bit_rate) / self.codec.bit_rate > 0.1 ): self.buffer_data = b"" self.buffer_pts = None self.codec = None
'''*Add these two lines*** self.codec = None self.target_bitrate = 500000 '''****''' if self.codec is None: try: self.codec, self.codec_buffering = create_encoder_context( "h264_omx", frame.width, frame.height, bitrate=self.target_bitrate ) except Exception: self.codec, self.codec_buffering = create_encoder_context( "libx264", frame.width, frame.height, bitrate=self.target_bitrate, )
TRANS_BY_GPT3
@xiaozhihong I tried another method, which is converting the pixel format, resetting the pts and time_base. Although I'm not quite clear about the principle, it does work. I'm not sure if this approach has any issues. The test script has been uploaded. srs_client.zip 。' translates to '.' in English.
TRANS_BY_GPT3
@qiubc you can refer to this solution on Zhihu: https://zhuanlan.zhihu.com/p/387772163. It might be helpful for you.
TRANS_BY_GPT3
@CodeIsWorld Okay, I will try your solution and then come back.
TRANS_BY_GPT3
Thank you all for the investigation and analysis. It seems that defining it as insufficient clarity is more appropriate, and it requires adjusting the streaming parameters.
TRANS_BY_GPT3
Description aiortc pushes to SRS, but the pulled stream appears flickering and blurry.
Replay
How to replay bug?
How to replay bug?
Expected behavior
Expected behavior
TRANS_BY_GPT3