2025-02-20 14:06:23 +08:00
|
|
|
import asyncio
|
|
|
|
|
import json
|
|
|
|
|
import logging
|
|
|
|
|
import os
|
|
|
|
|
|
|
|
|
|
import aiohttp_cors
|
|
|
|
|
from aiohttp import web
|
|
|
|
|
from aiortc import MediaStreamTrack, RTCPeerConnection, RTCSessionDescription, RTCConfiguration, RTCRtpCodecCapability
|
|
|
|
|
from aiortc.contrib.media import MediaBlackhole, MediaPlayer, MediaRecorder, MediaRelay
|
|
|
|
|
|
|
|
|
|
ROOT = os.path.dirname(__file__)
|
|
|
|
|
|
|
|
|
|
web.WebSocketResponse()
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
pcs = set()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async def offer(request):
|
2025-04-12 23:53:05 +08:00
|
|
|
params = await request.json_str()
|
2025-02-20 14:06:23 +08:00
|
|
|
offer = RTCSessionDescription(sdp=params["sdp"], type=params["type"])
|
|
|
|
|
pc = RTCPeerConnection(RTCConfiguration([]))
|
|
|
|
|
pcs.add(pc)
|
|
|
|
|
player = MediaPlayer(os.path.join(ROOT, "demo-instruct.wav"))
|
|
|
|
|
rc = pc.addTransceiver(player.video, 'sendonly')
|
|
|
|
|
rc.setCodecPreferences([RTCRtpCodecCapability(mimeType='video/H264',
|
|
|
|
|
clockRate=90000,
|
|
|
|
|
channels=None,
|
|
|
|
|
parameters={
|
|
|
|
|
'level-asymmetry-allowed': '1',
|
|
|
|
|
'packetization-mode': '1',
|
|
|
|
|
'profile-level-id': '42e01f'
|
|
|
|
|
})])
|
|
|
|
|
await pc.setRemoteDescription(offer)
|
|
|
|
|
answer = await pc.createAnswer()
|
|
|
|
|
await pc.setLocalDescription(answer)
|
|
|
|
|
return web.Response(
|
|
|
|
|
content_type="application/json",
|
|
|
|
|
text=json.dumps(
|
|
|
|
|
{"sdp": pc.localDescription.sdp, "type": pc.localDescription.type}
|
|
|
|
|
),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async def on_shutdown(app):
|
|
|
|
|
# close peer connections
|
|
|
|
|
coros = [pc.close() for pc in pcs]
|
|
|
|
|
await asyncio.gather(*coros)
|
|
|
|
|
pcs.clear()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
app = web.Application()
|
|
|
|
|
app.on_shutdown.append(on_shutdown)
|
|
|
|
|
app.router.add_post("/offer", offer)
|
|
|
|
|
|
|
|
|
|
cors = aiohttp_cors.setup(app, defaults={
|
|
|
|
|
"*": aiohttp_cors.ResourceOptions(
|
|
|
|
|
allow_credentials=True,
|
|
|
|
|
expose_headers="*",
|
|
|
|
|
allow_headers="*"
|
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
for route in list(app.router.routes()):
|
|
|
|
|
cors.add(route)
|
|
|
|
|
web.run_app(
|
|
|
|
|
app, access_log=None, host='0.0.0.0', port=8081
|
|
|
|
|
)
|