How do I trim a video from a video element in HTML/JavaScript?

Viewed 18

I have created an app in HTML and JavaScript where the screen and system sounds are recorded, and then when the user clicks "stop recording", a video element containing the recorded video appears. I would like to add functionality that allows the user to select a starting point and ending point, and trim the video to that selected section. Here is the code that I already have:

<!DOCTYPE html>
<html>

<head>
    <style>
        .videoBox {
            border-style: solid;
            border-color: black;
            width: 310px;
            height: 310px;
            margin-bottom: 20px;
        }

        .videoControls {
            margin-left: 50px;
            margin-top: 50px;
        }

        .playOrPauseButton {
            margin-bottom: 10px;
        }

        .endButton {
            margin-left: 10px;
        }

        .savingInfo {
            margin-top: 10px;
        }
    </style>
</head>

<body>
    <input type="hidden" id="recording" value="0" />
    <div class="videoBox">
        <div class="videoControls">
            <div class="playOrPauseButton">
                <button type="button" id="record" onclick="playOrPause()">Start Recording</button>
                <div class="recordingTime" id="recordingTime"></div>
            </div>
            <div class="endButton">
                <a id="downloadLink"><button type="button" id="endRecording" onclick="stopRecording()">Save
                        Video</button></a>
            </div>
            <div class="savingInfo">
                Your video will download, and it will also appear below when you save your video.
            </div>
        </div>
    </div>
    <div id="videoItself" class="videoItself"></div>


    <script>
        numberOfClicks = 1;
        let chunks = [];
        let mediaStream = null;
        let recorder = null;
        let seconds = 0;
        let videoNumber = 1;
        let filename = "";
        let videoLink = document.getElementById("downloadLink");
        let videoURL = "";

        async function setupMediaStream() {
            mediaStream = await navigator.mediaDevices.getDisplayMedia({ video: true, audio: true });
            recorder = new MediaRecorder(mediaStream);
            recorder.addEventListener("dataavailable", function (e) {
                chunks.push(e.data);
            });
            recorder.onstop = function () {
                document.getElementById("videoItself").innerHTML = "";
                if (filename.trim().length == 0) {
                    filename = "video " + videoNumber;
                }
                videoNumber++;
                let mostRecentChunk = [];
                mostRecentChunk.push(chunks[chunks.length - 1]);
                let blob = new Blob(mostRecentChunk, { 'type': 'video/mp4' });
                videoURL = window.URL.createObjectURL(blob);
                videoLink.setAttribute("href", videoURL);
                videoLink.setAttribute("download", filename);
                document.getElementById("endRecording").click();
                videoLink.removeAttribute("download");
                videoLink.removeAttribute("href");
                document.getElementById("recordingTime").innerHTML = "";
                document.getElementById("recording").value = 0;
                document.getElementById("record").innerHTML = "Start Recording";
                let video = document.createElement("video");
                video.src = videoURL;
                video.controls = true;
                video.style.width = "400px";
                video.style.height = "400px";
                video.setAttribute("id", "theVideo");
                document.getElementById("videoItself").appendChild(video);
                let seekBox = document.createElement("input");
                seekBox.setAttribute("type", "textbox");
                seekBox.setAttribute("id", "seekBox");
                let seekButton = document.createElement("button");
                seekButton.setAttribute("id", "seekButton");
                seekButton.innerHTML = "Seek Time (seconds)";
                seekButton.setAttribute("onclick", "seekTime()");
                let videoLength = document.createElement("p");
                videoLength.setAttribute("id", "videoLength");
                document.getElementById("videoItself").appendChild(seekBox);
                document.getElementById("videoItself").appendChild(seekButton);
                videoLength.innerHTML = "The length of the video is " + seconds + " seconds";
               document.getElementById("videoItself").appendChild(videoLength);
               seconds = 0;
               
            };
        }

        setupMediaStream();
        
        function seekTime() {
          let seekBox = document.getElementById("seekBox");
          let video = document.getElementById("theVideo");
          video.currentTime = parseInt(seekBox.value);
        }

        function playOrPause() {
            const recording = parseInt(document.getElementById("recording").value);
            recording == 0 ? record() : pause();
        }

        function record() {
            if (recorder != null) {
                try {
                    recorder.start();
                } catch (err) {
                    recorder.resume();
                }
                myInterval = setInterval(countTime, 1000);
                document.getElementById("recording").value = 1;
                document.getElementById("record").innerHTML = "Pause";
            } else {
                console.log("You must grant permission for the app to share your screen and use your microphone");
            }
        }

        function pause() {
            if (recorder != null) {
                recorder.pause();
                clearInterval(myInterval);
                document.getElementById("recording").value = 0;
                document.getElementById("record").innerHTML = "Continue Recording";
                let timeLabel = document.getElementById("recordingTime").innerHTML;
                document.getElementById("recordingTime").innerHTML = "" + recorder.state + ": " + timeLabel.substring(timeLabel.indexOf(":") + 1, timeLabel.length);
            } else {
                console.log("You must grant permission for the app to share your screen and use your microphone");
            }
        }

        function stopRecording() {
            if (recorder != null) {
                if (recorder.state != "inactive") {
                    pause();
                    filename = prompt("Save As: (Do not include the dot file extension)", "video " + videoNumber);
                    if (filename != null) {
                        recorder.stop();
                    }
                }
            } else {
                console.log("You must grant permission for the app to share your screen and use your microphone");
            }
        }

        function countTime() {
            seconds++;
            let hours = Math.floor(seconds / 3600);
            let minutes = Math.floor((seconds - (hours * 3600)) / 60);
            let secs = seconds - (hours * 3600) - (minutes * 60);
            let hourString = "";
            if (hours < 10) {
                hourString += "0";
            }
            hourString += hours;
            let minuteString = "";
            if (minuteString < 10) {
                minuteString += "0";
            }
            minuteString += minutes;
            let secString = "";
            if (secs < 10) {
                secString += "0";
            }
            secString += secs;
            let timeString = hourString + ":" + minuteString + ":" + secString;
            document.getElementById("recordingTime").innerHTML = "" + recorder.state + ": " + timeString;
        }

    </script>
</body>

</html>

Now, what I am struggling to figure out is this: What is the entity that contains the actual video data with timestamps and everything? To better explain what I am asking, what is it that I would have to manipulate in order to trim the video? Would I have to do something with the blob object that was used to create the video as seen here?:

let blob = new Blob(mostRecentChunk, { 'type': 'video/mp4' });
videoURL = window.URL.createObjectURL(blob);

I tried doing something with mediaStream.getVideoTracks(), but that doesn't do anything. Can anyone please tell me what it is that I would have to manipulate?

0 Answers
Related