nnnLik
@nnnLik
Capybara god

Как передать текст после обработки видео используя WebRTC?

Привет.

Моя задача - получить с клиента видеопоток с вебки, проанализировать его и вернуть результат в виде строки. Читая документацию aiortc и смотря их примеры на гите, смог сделать лишь такой вариант:

async def offer(request):
    params = await request.json()
    offer = RTCSessionDescription(sdp=params["sdp"], type=params["type"])

    pc = RTCPeerConnection()
    pcs.add(pc)

    await server(pc, offer)

    return web.Response(
        content_type="application/json",
        text=json.dumps(
            {"sdp": pc.localDescription.sdp, "type": pc.localDescription.type}
        ),
    )

pcs = set()

async def server(pc, offer):
    @pc.on("connectionstatechange")
    async def on_connectionstatechange():
        print("Connection state is %s" % pc.connectionState)
        if pc.connectionState == "failed":
            await pc.close()
            pcs.discard(pc)

    @pc.on("track")
    def on_track(track):
        print("======= received track: ", track)
        if track.kind == "video":
            global new_video_track
            new_video_track = Sign(track)
            pc.addTrack(new_video_track)

    @pc.on("datachannel")
    def on_datachannel(channel):
        global new_video_track
        new_video_track.channel = channel
        print("mounted channel")

        @channel.on("message")
        async def on_message(message):
            if isinstance(message, str):
                data = message.encode("utf-8")
            else:
                data = message
            print("receive data: ", data)

    await pc.setRemoteDescription(offer)
    answer = await pc.createAnswer()
    await pc.setLocalDescription(answer)


async def on_shutdown(app):
    # close peer connections
    coros = [pc.close() for pc in pcs]
    await asyncio.gather(*coros)
    pcs.clear()

class Sign(VideoStreamTrack):
    kind = "video"

    def __init__(self, track):
        super().__init__()
        self.track = track
        self.channel = None

    async def recv(self):
        frame = await self.track.recv()
        
       # получаю необходимый результат

        if self.channel and self.sentence:
                self.channel.send(json.dumps({'word': self.sentence}))
        return frame


но такой результат не устраивает, так как обратно нужно вернуть кадр. Как сделать так чтобы возвращалось только моё слово.

Вот клиент
var pc = null;
var localVideo = document.querySelector("video#localVideo");
var serverVideo = document.querySelector("video#serverVideo");

navigator.mediaDevices.getUserMedia({
	video: {

		height: 1080,
		width: 1920,

		frameRate: {
			max: 10
		}	
}

}).then(stream => {
	localVideo.srcObject = stream;
	localVideo.addEventListener('loadedmetadata', () => {
		localVideo.play();
	});
});

function negotiate () {
	return pc.createOffer().then(function (offer) {
		return pc.setLocalDescription(offer);
	}).then(function () {
		// wait for ICE gathering to complete
		return new Promise(function (resolve) {
			if (pc.iceGatheringState === 'complete') {
				resolve();
			} else {
				function checkState () {
					if (pc.iceGatheringState === 'complete') {
						pc.removeEventListener('icegatheringstatechange', checkState);
						resolve();
					}
				}
				pc.addEventListener('icegatheringstatechange', checkState);
			}
		});
	}).then(function () {
		var offer = pc.localDescription;
		return fetch('/offer', {
			body: JSON.stringify({
				sdp: offer.sdp,
				type: offer.type,
			}),
			headers: {
				'Content-Type': 'application/json'
			},
			method: 'POST'
		});
	}).then(function (response) {
		return response.json();
	}).then(function (answer) {
		return pc.setRemoteDescription(answer);
	}).catch(function (e) {
		alert(e);
	});
}

function start () {
	var config = {
		sdpSemantics: 'unified-plan',
		iceServers: [{ urls: ['stun:stun.l.google.com:19302'] }]
	};

	pc = new RTCPeerConnection(config);

	localVideo.srcObject.getVideoTracks().forEach(track => {
		pc.addTrack(track);
	});
	pc.addEventListener('track', function (evt) {
		console.log("receive server video");
		if (evt.track.kind == 'video') {
			serverVideo.srcObject = evt.streams[0];
		}
	});
	ch = pc.createDataChannel("chat", {
		ordered: false,
		maxRetransmits: 0,
	});
	ch.addEventListener("message", function (evt) {
		console.log(Date.now() - JSON.parse(evt.data).now);
	});

	document.getElementById('start').style.display = 'none';
	negotiate();
	document.getElementById('stop').style.display = 'inline-block';
}



function stop () {
	document.getElementById('stop').style.display = 'none';
	setTimeout(function () {
		pc.close();
	}, 500);
}


Заранее спасибо и простите за большие куски кода.
  • Вопрос задан
  • 130 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы