server.py file
import asyncio, json, os, cv2
from aiohttp import web
from aiortc import (RTCPeerConnection, RTCSessionDescription, VideoStreamTrack)
from av import VideoFrame
import numpy as np
ROOT = os.path.dirname(__file__)
class LocalVideoStream(VideoStreamTrack):
def __init__(self):
super().__init__()
self.cap = cv2.VideoCapture("demo.avi")
async def recv(self):
pts, time_base = await self.next_timestamp()
ret, frame = self.cap.read()
vf = VideoFrame.from_ndarray(frame)
vf.pts = pts
vf.time_base = time_base
return vf
async def index(request):
content = open(os.path.join(ROOT, 'index.html'), 'r').read()
return web.Response(content_type='text/html', text=content)
async def javascript(request):
content = open(os.path.join(ROOT, 'client.js'), 'r').read()
return web.Response(content_type='application/javascript', text=content)
pcs = []
local_video = LocalVideoStream()
async def offer(request):
params = await request.json()
offer = RTCSessionDescription(
sdp=params['sdp'],
type=params['type'])
pc = RTCPeerConnection()
pcs.append(pc)
# Add local media
pc.addTrack(local_video)
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)
if __name__ == '__main__':
app = web.Application()
app.on_shutdown.append(on_shutdown)
app.router.add_get('/', index)
app.router.add_get('/client.js', javascript)
app.router.add_post('/offer', offer)
web.run_app(app)
client.js file
var pc = new RTCPeerConnection();
// register some listeners to help debugging
pc.addEventListener('icegatheringstatechange', function() {
console.warn(pc.iceGatheringState);
}, false);
pc.addEventListener('iceconnectionstatechange', function() {
console.warn(pc.iceConnectionState);
}, false);
pc.addEventListener('signalingstatechange', function() {
console.warn(pc.signalingState);
}, false);
// connect audio / video
pc.addEventListener('track', function(evt) {
console.log('incomming track')
console.log(evt);
if (evt.track.kind == 'video') {
document.getElementById('video').srcObject = evt.streams[0];
console.log('video elem added');
} else {
document.getElementById('audio').srcObject = evt.streams[0];
}
});
function negotiate() {
return pc.createOffer({offerToReceiveVideo: true, offerToReceiveAudio: false}).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;
console.log('Offer SDP');
console.log(offer.sdp);
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) {
console.log('Answer SDP');
console.log(answer.sdp);
return pc.setRemoteDescription(answer);
});
}
function start() {
document.getElementById('start').style.display = 'none';
negotiate();
document.getElementById('stop').style.display = 'inline-block';
}
function stop() {
document.getElementById('stop').style.display = 'none';
// close peer connection
setTimeout(function() {
pc.close();
}, 500);
}
index.html file
<html>
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>RTC Broadcast</title>
<style>
button {
padding: 8px 16px;
}
video {
width: 60%;
}
</style>
</head>
<body>
<div id="media">
<h1>Video</h1>
<audio id="audio" autoplay="true"></audio>
<video id="video" autoplay="true"></video>
</div>
<button id="start" onclick="start()">Start</button>
<button id="stop" style="display: none" onclick="stop()">Stop</button>
<script src="client.js"></script>
</body>
</html>
I ran the following code in ec2 ubuntu 16.04 (after installing aiortc,opencv via pip) instance from port 8080 (in security group of ec2 allowed all traffic). I could see the page in public ip address of the instance but the video is not visible. I have tried running the same code in both ubuntu and windows machine and it works properly. Does anyone have any idea why this is happening?

server.py file
client.js file
index.html file
I ran the following code in ec2 ubuntu 16.04 (after installing aiortc,opencv via pip) instance from port 8080 (in security group of ec2 allowed all traffic). I could see the page in public ip address of the instance but the video is not visible. I have tried running the same code in both ubuntu and windows machine and it works properly. Does anyone have any idea why this is happening?