importasyncioimportloggingimportosimporttempfilefrompyrtmpimportStreamClosedException,RTMPProtocolfrompyrtmp.messagesimportSessionManagerfrompyrtmp.messages.audioimportAudioMessagefrompyrtmp.messages.commandimportNCConnect,NCCreateStream,NSPublish,NSCloseStream,NSDeleteStreamfrompyrtmp.messages.dataimportMetaDataMessagefrompyrtmp.messages.protocolcontrolimportWindowAcknowledgementSize,SetChunkSize,SetPeerBandwidthfrompyrtmp.messages.usercontrolimportStreamBeginfrompyrtmp.messages.videoimportVideoMessagefrompyrtmp.misc.flvdumpimportFLVFile,FLVMediaTypelogging.basicConfig(level=logging.DEBUG)logger=logging.getLogger(__name__)logger.setLevel(logging.DEBUG)asyncdefsimple_controller(reader,writer):session=SessionManager(reader=reader,writer=writer)flv=Nonetry:logger.debug(f'Client connected {session.peername}')# do handshakeawaitsession.handshake()# read chunksasyncforchunkinsession.read_chunks_from_stream():message=chunk.as_message()logger.debug(f"Receiving {str(message)}{message.chunk_id}")ifisinstance(message,NCConnect):session.write_chunk_to_stream(WindowAcknowledgementSize(ack_window_size=5000000))session.write_chunk_to_stream(SetPeerBandwidth(ack_window_size=5000000,limit_type=2))session.write_chunk_to_stream(StreamBegin(stream_id=0))session.write_chunk_to_stream(SetChunkSize(chunk_size=8192))session.writer_chunk_size=8192session.write_chunk_to_stream(message.create_response())awaitsession.drain()logger.debug("Response to NCConnect")elifisinstance(message,WindowAcknowledgementSize):passelifisinstance(message,NCCreateStream):session.write_chunk_to_stream(message.create_response())awaitsession.drain()logger.debug("Response to NCCreateStream")elifisinstance(message,NSPublish):# create flv file at tempflv=FLVFile(os.path.join(tempfile.gettempdir(),message.publishing_name))session.write_chunk_to_stream(StreamBegin(stream_id=1))session.write_chunk_to_stream(message.create_response())awaitsession.drain()logger.debug("Response to NSPublish")elifisinstance(message,MetaDataMessage):# Write meta data to fileflv.write(0,message.to_raw_meta(),FLVMediaType.OBJECT)elifisinstance(message,SetChunkSize):session.reader_chunk_size=message.chunk_sizeelifisinstance(message,VideoMessage):# Write video data to fileflv.write(message.timestamp,message.payload,FLVMediaType.VIDEO)elifisinstance(message,AudioMessage):# Write data data to fileflv.write(message.timestamp,message.payload,FLVMediaType.AUDIO)elifisinstance(message,NSCloseStream):passelifisinstance(message,NSDeleteStream):passelse:logger.debug(f"Unknown message {str(message)}")exceptStreamClosedExceptionasex:logger.debug(f"Client {session.peername} disconnected!")finally:ifflv:flv.close()asyncdefserve_rtmp(use_protocol=True):loop=asyncio.get_running_loop()ifuse_protocolisTrue:server=awaitloop.create_server(lambda:RTMPProtocol(controller=simple_controller,loop=loop),'0.0.0.0',1935)else:server=awaitasyncio.start_server(simple_controller,'0.0.0.0',1935)addr=server.sockets[0].getsockname()logger.info(f'Serving on {addr}')asyncwithserver:awaitserver.serve_forever()defwrapper(port:int):asyncio.run(serve_rtmp(port=port))IS_DEBUG=TrueNUM_PROCESS=2if__name__=="__main__":ifIS_DEBUGisTrue:wrapper(1935)else:frommultiprocessingimportProcessimportuvloopuvloop.install()process=[]foriinrange(NUM_PROCESS):p=Process(target=wrapper,args=(1935+i+1,))p.start()process.append(p)forpinprocess:p.join()