Live Video Streaming from IP camera to Application

Hi,

I am trying to stream live video from an IP camera to my Anvil application using Custom HTML and JS (RTSP streaming link), I have a VLC player to stream this RTSP link embed in my HTML code but I am receiving [An internal error has occurred] when I am trying to run the application. Is there any other easier way to live stream video onto the Application? Please suggest.

Hi @abhijith.rao.teslavn, and welcome to the forum!

[An internal error has occurred] means there was an error in your JavaScript code somewhere. The best thing to do is investigate using your browser console.

Thank you so much for your reply, I am new to JS can you help me out here? Below is my HTML code for the player and the JS code for the controls,

HTML Code:

<center style="font-style:italic; color:#888; margin: 3em;">
  <div style = " width: 503px; height: 377px; background-color: black; position: absolute; left:0; top:0;">
    <link href="_/theme/videoplayer.css" rel="stylesheet" type="text/css" media="all">
<div class="player">
	<OBJECT classid="clsid:9BE31822-FDAD-461B-AD51-BE1D1C159921"
		codebase="http://downloads.videolan.org/pub/video ... /axvlc.cab"
		id="vlc" events="True">
		<param name="Src" value="rtsp://192.168.1.100:554/user=admin&password=admin123&channel=1&stream=0.sdp?" /> (J-TECH IP cam)
		<param name="ShowDisplay" value="True" />
		<param name="AutoLoop" value="False" />
		<param name="AutoPlay" value="True" />
	</OBJECT>
	<div class="player__controls">
    <div class="progress">
      <div class="progress__filled"></div>
    </div>
    <button class="player__button toggle" title="Toggle Play">
     <svg class="" width="16" height="16" viewBox="0 0 16 16"><title>play</title><path d="M3 2l10 6-10 6z"></path></svg>
     </button>
    <input type="range" name="volume" class="player__slider" min="0" max="1" step="0.05" value="1">
    <input type="range" name="playbackRate" class="player__slider" min="0.5" max="2" step="0.1" value="1">
    <button data-skip="-10" class="player__button">« 10s</button>
    <button data-skip="25" class="player__button">25s »</button>
    <button class="player__button exit" title="Exit Camera">EXIT</button>
  </div>
<script src="_/theme/videoplayer.js"></script>
    </div>
  </div>
</center>

JS Code:
/* Get Our Elements */
const player = document.querySelector(".player");
const video = player.querySelector(".viewer");
const progress = player.querySelector(".progress");
const progressBar = player.querySelector(".progress__filled");
const toggle = player.querySelector(".toggle");
const skipButtons = player.querySelectorAll("[data-skip]");
const exit = player.querySelector(".exit");
const ranges = player.querySelectorAll(".player__slider");

/* Build out functions */
function togglePlay() {
  const method = video.paused ? "play" : "pause";
  video[method]();
}

function updateButton() {
  const togglePlayBtn = document.querySelector('.toggle');
  if(this.paused) {
    toggleBtn.innerHTML = `<svg class="" width="16" height="16" viewBox="0 0 16 16"><title>play</title><path d="M3 2l10 6-10 6z"></path></svg>`;  
  } else {
    toggleBtn.innerHTML = `<svg width="16" height="16" viewBox="0 0 16 16"><title>pause</title><path d="M2 2h5v12H2zm7 0h5v12H9z"></path></svg>`;
  }
}

function skip() {
  video.currentTime += parseFloat(this.dataset.skip);
}

function handleRangeUpdate() {
  video[this.name] = this.value;
}

function handleProgress() {
  const percent = video.currentTime / video.duration * 100;
  progressBar.style.flexBasis = `${percent}%`;
}

function scrub(e) {
  const scrubTime = e.offsetX / progress.offsetWidth * video.duration;
  video.currentTime = scrubTime;
}

function exitPlayer(){
  var linkElement = this;
  anvil.call(linkElement, "exit_player")
}

/* Hook up the event listeners */
video.addEventListener("click", togglePlay);
video.addEventListener("play", updateButton);
video.addEventListener("pause", updateButton);
video.addEventListener("timeupdate", handleProgress);

toggle.addEventListener("click", togglePlay);
skipButtons.forEach(button => button.addEventListener("click", skip));
ranges.forEach(range => range.addEventListener("change", handleRangeUpdate));
ranges.forEach(range => range.addEventListener("mousemove", handleRangeUpdate));
exit.addEventListener("click", exitPlayer);

let mousedown = false;
progress.addEventListener("click", scrub);
progress.addEventListener("mousemove", e => mousedown && scrub(e));
progress.addEventListener("mousedown", () => (mousedown = true));
progress.addEventListener("mouseup", () => (mousedown = false));