My security camera provides frames in H264 codec via RTSP. Below is my C++ code with FFMPEG library getting frames from from the camera.
std::string read_frame() {
AVPacket *packet;
packet= av_packet_alloc();
if (!packet) return "";
while (av_read_frame(format_context, packet) >= 0) {
if (packet->stream_index != stream_index) continue;
if (avcodec_send_packet(codec_context, packet) < 0) return "";
fflush(stdout);
int response = avcodec_receive_frame(codec_context, frame);
if (response == AVERROR(EAGAIN) || response == AVERROR_EOF) {
continue;
} else if (response < 0) {
return "";
}
// std::cout << codec_context->codec_id << " == " << AV_CODEC_ID_H264 << std::endl;
// std::string str = decode_base64(encode_base64(packet->data, packet->size)); // I did try this to get binary data from AV Packet
std::string str = decode_base64(encode_base64(frame->data, (frame->width * frame->height))); // I did try this to get binary data from AV Frame.
fflush(stdout);
return str;
}
}
I use Base64 encode function to extract the frame data out of the AV Packet or AV Frame and then use the Base64 decode function to get raw binary data as a string. My web socket pushes this raw binary data (H264) to the web page.
Due to this answer: Play raw h264 live stream in browser. Below is my JavaScript code that connects to the web socket.
script type="text/javascript" src="dist/jmuxer.min.js"></script>
<video id="player"></video>
<script>
var jmuxer = new JMuxer({
node: 'player',
mode: 'video',
debug: true
});
const ws = new WebSocket('ws://127.0.0.1:port_number', ["binary"]);
ws.addEventListener('message', event => {
event.data.arrayBuffer().then(res => {
jmuxer.feed({
video: new Uint8Array(res)
});
});
// Have also tried this, but did not work.
// jmuxer.feed({
// video: new Uint8Array(event.data)
//// video: new Uint8Array(event.data.arrayBuffer()) // Also tried this.
//});
});
</script>
My web socket does work well since I do receive binary data on the web page. No doubt about that. My read_frame()
C++ function also works since I do see binary data with std::cout << read_frame() << std::endl;
and it is in H264 codec std::cout << codec_context->codec_id << " == " << AV_CODEC_ID_H264 << std::endl;
How I can show frames on the web page with the H264 binary data? Any other JavaScript libraries that you have ever worked with and you know it works well?