Recherche avancée

Médias (91)

Autres articles (50)

  • La file d’attente de SPIPmotion

    28 novembre 2010, par

    Une file d’attente stockée dans la base de donnée
    Lors de son installation, SPIPmotion crée une nouvelle table dans la base de donnée intitulée spip_spipmotion_attentes.
    Cette nouvelle table est constituée des champs suivants : id_spipmotion_attente, l’identifiant numérique unique de la tâche à traiter ; id_document, l’identifiant numérique du document original à encoder ; id_objet l’identifiant unique de l’objet auquel le document encodé devra être attaché automatiquement ; objet, le type d’objet auquel (...)

  • Submit enhancements and plugins

    13 avril 2011

    If you have developed a new extension to add one or more useful features to MediaSPIP, let us know and its integration into the core MedisSPIP functionality will be considered.
    You can use the development discussion list to request for help with creating a plugin. As MediaSPIP is based on SPIP - or you can use the SPIP discussion list SPIP-Zone.

  • Personnaliser en ajoutant son logo, sa bannière ou son image de fond

    5 septembre 2013, par

    Certains thèmes prennent en compte trois éléments de personnalisation : l’ajout d’un logo ; l’ajout d’une bannière l’ajout d’une image de fond ;

Sur d’autres sites (7420)

  • How to stream Audio/Video using Node.js express streaming with ffmpeg and flowplayer usage ??

    30 septembre 2014, par iknowv

    I want to create node server which streams media file to public using express module in chunks

    Server.js ( This is nodejs server which works for me but without chunks )

               var express = require('express');
               var app = express();

               var http = require('http');
               var fs = require('fs');
               var path = require('path');
               var ext = /[\w\d_-]+\.[\w\d]+$/;

               ffmpeg_path = "ffmpeg\\";
               app.get('/player', function(req, res){
               res.writeHead(200, {'Content-Type': 'text/html'});
               fs.createReadStream('video.html').pipe(res);
               });

               app.get('/audio', function(req, res){

               myParam = [];
               myParam.push("-i","","-f","mp3","pipe:1");
               myParam[1] = 'media\\example_aac.m4a';
               var child_process = require("child_process");
               ffmpeg = child_process.spawn(ffmpeg_path + 'ffmpeg.exe',myParam);  
               ffmpeg.stderr.on('data', function(data)
               {
                   console.log('ffmpeg .error=' + data.toString());
               });
                res.writeHead(200, {
                  'Content-Type': 'audio/mp3'
                });
               ffmpeg.stdout.pipe(res);
               });


               app.get('/video', function(req, res){

               myParam = [];
               myParam.push("-i","","-f","flv","pipe:1");
               myParam[1] = 'media\\example_video.wmv';
               var child_process = require("child_process");
               ffmpeg = child_process.spawn(ffmpeg_path + 'ffmpeg.exe',myParam);  
               ffmpeg.stderr.on('data', function(data)
               {
                   console.log('ffmpeg .error=' + data.toString());
               });
               /*ffmpeg.stdout.on('data', function(data)
               {
               //var buff = new Buffer(data).toString();
               //res.send(buff);
               });*/
               res.writeHead(200, {
                  'Content-Type': 'video/flv'
                });
               ffmpeg.stdout.pipe(res);
               });

               app.listen(3000);

    =================================================

    video.html

                    <code class="echappe-js">&lt;script src=&quot;http://releases.flowplayer.org/js/flowplayer-3.2.13.min.js&quot;&gt;&lt;/script&gt;
                
    Audio Player
    Video Player
    &lt;script type=&quot;text/javascript&quot;&gt;<br />
               $f(&quot;player&quot;, &quot;http://releases.flowplayer.org/swf/flowplayer-3.2.18.swf&quot;, {<br />
               clip: {<br />
                  autoPlay: false,<br />
                  url: &quot;http://localhost:3000/audio&quot;<br />
               },<br />
                plugins: {<br />
                   controls: {<br />
                       fullscreen: false,<br />
                       height: 30,<br />
                       autoHide: false<br />
                   }<br />
               }<br />
    <br />
               });<br />
               &lt;/script&gt;
    &lt;script type=&quot;text/javascript&quot;&gt;<br />
               flowplayer(&quot;videoplayer&quot;, &quot;http://localhost/flowplayer/flowplayer.commercial-3.2.2.swf&quot;, {<br />
                   clip: {<br />
                       autoPlay: false,<br />
                       autoBuffering: false,<br />
                       scaling: 'fit',<br />
                       url: 'http://localhost:3000/video',<br />
                       captionUrl: ''<br />
                       },<br />
                       plugins: {<br />
                   controls: {<br />
                       fullscreen: false,<br />
                       height: 30,<br />
                       autoHide: false<br />
                   }<br />
               }<br />
                   }<br />
               );<br />
               &lt;/script&gt;
  • Gstreamer pipeline to scale down video before streaming

    20 novembre 2014, par r3dsm0k3

    Here is what Im trying to achieve.

    Im streaming from a Logitech C920 camera on beaglebone black with gstreamer. I have to save a copy of the video saved locally while it is streaming. I have achieved that with tee.
    Logitech camera gives h264 encoded video at a certain bitrate, mostly very high.

    Im streaming from a moving car on 3G, and the network is not good enough to send the stream to nginx-rtmp server Im using to re-distribute thus gives strong artifacts in the result.

    Im able to alter the bitrate of captured video using uvch264.
    But then, the locally saved video also would have lower bitrate.

    Is there anyway of capturing a higher bitrate 1080p video from the camera and sending a lower resolution, lower bitrate video the streaming server ?

    Following is the pipeline I have currently.

    gst-launch-1.0 -v -e uvch264src initial-bitrate=400000 average-bitrate=400000 iframe-period=3000  device=/dev/video0 name=src auto-start=true  src.vidsrc ! queue ! video/x-h264,width=1920,height=1080,framerate=30/1 ! h264parse ! flvmux streamable=true  name=flvmuxer ! queue ! tee name=t ! queue ! filesink location=/mnt/test.flv t. ! queue ! rtmpsink location=$SERVER/hls/$CAM1

    I could also try sending the higher bitrate video to a udpsink instead of rtmpsink and with another gstreamer process parallely and takes the data using a udpsink and probably post process/ re-encode and send to rtmp server.

    Im also limited by the processing speed BeagleBone has to do for encoding the videos. Currently Im trying for 1 camera and in the finished project I would like to have 2 cameras connected. Upload speed Im getting for the network is under 1Mbps.

    How do I solve this with less load on the BeagleBone ? Im very open to a new architecture as well.

  • Discord 24/7 video stream self-bot crashes after a couple hours

    21 juillet 2023, par angelo

    I've implemented this library to make a self-bot that streams videos from a local folder in a loop 24/7 (don't ask me why). I set up an ubuntu vps to run the bot and it works perfectly fine the first 2-3 hours, after that it gets more and more laggy until the server crashes.&#xA;pd : It's basically my first time using javascript and stole most of the code from this repo so don't bully me.

    &#xA;

    Here's the code :

    &#xA;

    import { Client, TextChannel, CustomStatus, ActivityOptions } from "discord.js-selfbot-v13";&#xA;import { command, streamLivestreamVideo, VoiceUdp, setStreamOpts, streamOpts } from "@dank074/discord-video-stream";&#xA;import config from "./config.json";&#xA;import fs from &#x27;fs&#x27;;&#xA;import path from &#x27;path&#x27;;&#xA;&#xA;const client = new Client();&#xA;&#xA;client.patchVoiceEvents(); //this is necessary to register event handlers&#xA;&#xA;setStreamOpts(&#xA;    config.streamOpts.width,&#xA;    config.streamOpts.height,&#xA;    config.streamOpts.fps,&#xA;    config.streamOpts.bitrateKbps,&#xA;    config.streamOpts.hardware_acc&#xA;)&#xA;&#xA;const prefix = &#x27;$&#x27;;&#xA;&#xA;const moviesFolder = config.movieFolder || &#x27;./movies&#x27;;&#xA;&#xA;const movieFiles = fs.readdirSync(moviesFolder);&#xA;let movies = movieFiles.map(file => {&#xA;    const fileName = path.parse(file).name;&#xA;    // replace space with _&#xA;    return { name: fileName.replace(/ /g, &#x27;&#x27;), path: path.join(moviesFolder, file) };&#xA;});&#xA;let originalMovList = [...movies];&#xA;let movList = movies;&#xA;let shouldStop = false;&#xA;&#xA;// print out all movies&#xA;console.log(`Available movies:\n${movies.map(m => m.name).join(&#x27;\n&#x27;)}`);&#xA;&#xA;const status_idle = () =>  {&#xA;    return new CustomStatus()&#xA;        .setState(&#x27;摸鱼进行中&#x27;)&#xA;        .setEmoji(&#x27;&#128031;&#x27;)&#xA;}&#xA;&#xA;const status_watch = (name) => {&#xA;    return new CustomStatus()&#xA;        .setState(`Playing ${name}...`)&#xA;        .setEmoji(&#x27;&#128253;&#x27;)&#xA;}&#xA;&#xA;// ready event&#xA;client.on("ready", () => {&#xA;    if (client.user) {&#xA;        console.log(`--- ${client.user.tag} is ready ---`);&#xA;        client.user.setActivity(status_idle() as ActivityOptions)&#xA;    }&#xA;});&#xA;&#xA;let streamStatus = {&#xA;    joined: false,&#xA;    joinsucc: false,&#xA;    playing: false,&#xA;    channelInfo: {&#xA;        guildId: &#x27;&#x27;,&#xA;        channelId: &#x27;&#x27;,&#xA;        cmdChannelId: &#x27;&#x27;&#xA;    },&#xA;    starttime: "00:00:00",&#xA;    timemark: &#x27;&#x27;,&#xA;}&#xA;&#xA;client.on(&#x27;voiceStateUpdate&#x27;, (oldState, newState) => {&#xA;    // when exit channel&#xA;    if (oldState.member?.user.id == client.user?.id) {&#xA;        if (oldState.channelId &amp;&amp; !newState.channelId) {&#xA;            streamStatus.joined = false;&#xA;            streamStatus.joinsucc = false;&#xA;            streamStatus.playing = false;&#xA;            streamStatus.channelInfo = {&#xA;                guildId: &#x27;&#x27;,&#xA;                channelId: &#x27;&#x27;,&#xA;                cmdChannelId: streamStatus.channelInfo.cmdChannelId&#xA;            }&#xA;            client.user?.setActivity(status_idle() as ActivityOptions)&#xA;        }&#xA;    }&#xA;    // when join channel success&#xA;    if (newState.member?.user.id == client.user?.id) {&#xA;        if (newState.channelId &amp;&amp; !oldState.channelId) {&#xA;            streamStatus.joined = true;&#xA;            if (newState.guild.id == streamStatus.channelInfo.guildId &amp;&amp; newState.channelId == streamStatus.channelInfo.channelId) {&#xA;                streamStatus.joinsucc = true;&#xA;            }&#xA;        }&#xA;    }&#xA;})&#xA;&#xA;client.on(&#x27;messageCreate&#x27;, async (message) => {&#xA;    if (message.author.bot) return; // ignore bots&#xA;    if (message.author.id == client.user?.id) return; // ignore self&#xA;    if (!config.commandChannels.includes(message.channel.id)) return; // ignore non-command channels&#xA;    if (!message.content.startsWith(prefix)) return; // ignore non-commands&#xA;&#xA;    const args = message.content.slice(prefix.length).trim().split(/ &#x2B;/); // split command and arguments&#xA;    if (args.length == 0) return;&#xA;&#xA;    const user_cmd = args.shift()!.toLowerCase();&#xA;&#xA;    if (config.commandChannels.includes(message.channel.id)) {&#xA;        switch (user_cmd) {&#xA;            case &#x27;play&#x27;:&#xA;                playCommand(args, message);&#xA;                break;&#xA;            case &#x27;stop&#x27;:&#xA;                stopCommand(message);&#xA;                break;&#xA;            case &#x27;playtime&#x27;:&#xA;                playtimeCommand(message);&#xA;                break;&#xA;            case &#x27;pause&#x27;:&#xA;                pauseCommand(message);&#xA;                break;&#xA;            case &#x27;resume&#x27;:&#xA;                resumeCommand(message);&#xA;                break;&#xA;            case &#x27;list&#x27;:&#xA;                listCommand(message);&#xA;                break;&#xA;            case &#x27;status&#x27;:&#xA;                statusCommand(message);&#xA;                break;&#xA;            case &#x27;refresh&#x27;:&#xA;                refreshCommand(message);&#xA;                break;&#xA;            case &#x27;help&#x27;:&#xA;                helpCommand(message);&#xA;                break;&#xA;            case &#x27;playall&#x27;:&#xA;                playAllCommand(args, message);&#xA;                break;&#xA;            case &#x27;stream&#x27;:&#xA;                streamCommand(args, message);&#xA;                break;&#xA;            case &#x27;shuffle&#x27;:&#xA;                shuffleCommand();&#xA;                break;&#xA;            case &#x27;skip&#x27;:&#xA;                //skip cmd&#xA;                break;&#xA;            default:&#xA;                message.reply(&#x27;Invalid command&#x27;);&#xA;        }&#xA;    }&#xA;});&#xA;&#xA;client.login("TOKEN_HERE");&#xA;&#xA;let lastPrint = "";&#xA;&#xA;async function playAllCommand(args, message) {&#xA;    if (streamStatus.joined) {&#xA;        message.reply("Already joined");&#xA;        return;&#xA;    }&#xA;&#xA;    // args = [guildId]/[channelId]&#xA;    if (args.length === 0) {&#xA;        message.reply("Missing voice channel");&#xA;        return;&#xA;    }&#xA;&#xA;    // process args&#xA;    const [guildId, channelId] = args.shift()!.split("/");&#xA;    if (!guildId || !channelId) {&#xA;        message.reply("Invalid voice channel");&#xA;        return;&#xA;    }&#xA;&#xA;    await client.joinVoice(guildId, channelId);&#xA;    streamStatus.joined = true;&#xA;    streamStatus.playing = false;&#xA;    streamStatus.starttime = "00:00:00";&#xA;    streamStatus.channelInfo = {&#xA;        guildId: guildId,&#xA;        channelId: channelId,&#xA;        cmdChannelId: message.channel.id,&#xA;    };&#xA;&#xA;    const streamUdpConn = await client.createStream();&#xA;&#xA;    streamUdpConn.voiceConnection.setSpeaking(true);&#xA;    streamUdpConn.voiceConnection.setVideoStatus(true);&#xA;&#xA;    playAllVideos(streamUdpConn); // Start playing videos&#xA;&#xA;    // Keep the stream open&#xA;&#xA;    streamStatus.joined = false;&#xA;    streamStatus.joinsucc = false;&#xA;    streamStatus.playing = false;&#xA;    lastPrint = "";&#xA;    streamStatus.channelInfo = {&#xA;        guildId: "",&#xA;        channelId: "",&#xA;        cmdChannelId: "",&#xA;    };&#xA;}&#xA;&#xA;async function playAllVideos(udpConn: VoiceUdp) {&#xA;&#xA;    console.log("Started playing video");&#xA;&#xA;    udpConn.voiceConnection.setSpeaking(true);&#xA;    udpConn.voiceConnection.setVideoStatus(true);&#xA;&#xA;    try {&#xA;        let index = 0;&#xA;&#xA;        while (true) {&#xA;            if (shouldStop) {&#xA;                break; // For the stop command&#xA;            }&#xA;&#xA;            if (index >= movies.length) {&#xA;                // Reset the loop&#xA;                index = 0;&#xA;            }&#xA;&#xA;            const movie = movList[index];&#xA;&#xA;            if (!movie) {&#xA;                console.log("Movie not found");&#xA;                index&#x2B;&#x2B;;&#xA;                continue;&#xA;            }&#xA;&#xA;            let options = {};&#xA;            options["-ss"] = "00:00:00";&#xA;&#xA;            console.log(`Playing ${movie.name}...`);&#xA;&#xA;            try {&#xA;                let videoStream = streamLivestreamVideo(movie.path, udpConn);&#xA;                command?.on(&#x27;progress&#x27;, (msg) => {&#xA;                    // print timemark if it passed 10 second sionce last print, becareful when it pass 0&#xA;                    if (streamStatus.timemark) {&#xA;                        if (lastPrint != "") {&#xA;                            let last = lastPrint.split(&#x27;:&#x27;);&#xA;                            let now = msg.timemark.split(&#x27;:&#x27;);&#xA;                            // turn to seconds&#xA;                            let s = parseInt(now[2]) &#x2B; parseInt(now[1]) * 60 &#x2B; parseInt(now[0]) * 3600;&#xA;                            let l = parseInt(last[2]) &#x2B; parseInt(last[1]) * 60 &#x2B; parseInt(last[0]) * 3600;&#xA;                            if (s - l >= 10) {&#xA;                                console.log(`Timemark: ${msg.timemark}`);&#xA;                                lastPrint = msg.timemark;&#xA;                            }&#xA;                        } else {&#xA;                            console.log(`Timemark: ${msg.timemark}`);&#xA;                            lastPrint = msg.timemark;&#xA;                        }&#xA;                    }&#xA;                    streamStatus.timemark = msg.timemark;&#xA;                });&#xA;                const res = await videoStream;&#xA;                console.log("Finished playing video " &#x2B; res);&#xA;            } catch (e) {&#xA;                console.log(e);&#xA;            }&#xA;&#xA;            index&#x2B;&#x2B;; // Pasar a la siguiente pel&#xED;cula&#xA;        }&#xA;    } finally {&#xA;        udpConn.voiceConnection.setSpeaking(false);&#xA;        udpConn.voiceConnection.setVideoStatus(false);&#xA;    }&#xA;&#xA;    command?.kill("SIGINT");&#xA;    // send message to channel, not reply&#xA;    (client.channels.cache.get(streamStatus.channelInfo.cmdChannelId) as TextChannel).send(&#x27;Finished playing video, timemark is &#x27; &#x2B; streamStatus.timemark);&#xA;    client.leaveVoice();&#xA;    client.user?.setActivity(status_idle() as ActivityOptions)&#xA;    streamStatus.joined = false;&#xA;    streamStatus.joinsucc = false;&#xA;    streamStatus.playing = false;&#xA;    lastPrint = ""&#xA;    streamStatus.channelInfo = {&#xA;        guildId: &#x27;&#x27;,&#xA;        channelId: &#x27;&#x27;,&#xA;        cmdChannelId: &#x27;&#x27;&#xA;    };&#xA;}&#xA;&#xA;function shuffleArray(array) {&#xA;    for (let i = array.length - 1; i > 0; i--) {&#xA;        const j = Math.floor(Math.random() * (i &#x2B; 1));&#xA;        [array[i], array[j]] = [array[j], array[i]];&#xA;    }&#xA;}&#xA;&#xA;function shuffleCommand() {&#xA;    shuffleArray(movList);&#xA;}&#xA;&#xA;async function playCommand(args, message) {&#xA;    if (streamStatus.joined) {&#xA;        message.reply(&#x27;Already joined&#x27;);&#xA;        return;&#xA;    }&#xA;&#xA;    // args = [guildId]/[channelId]&#xA;    if (args.length == 0) {&#xA;        message.reply(&#x27;Missing voice channel&#x27;);&#xA;        return;&#xA;    }&#xA;&#xA;    // process args&#xA;    const [guildId, channelId] = args.shift()!.split(&#x27;/&#x27;);&#xA;    if (!guildId || !channelId) {&#xA;        message.reply(&#x27;Invalid voice channel&#x27;);&#xA;        return;&#xA;    }&#xA;&#xA;    // get movie name and find movie file&#xA;    let moviename = args.shift()&#xA;    let movie = movies.find(m => m.name == moviename);&#xA;&#xA;    if (!movie) {&#xA;        message.reply(&#x27;Movie not found&#x27;);&#xA;        return;&#xA;    }&#xA;&#xA;    // get start time from args "hh:mm:ss"&#xA;    let startTime = args.shift();&#xA;    let options = {}&#xA;    // check if start time is valid&#xA;    if (startTime) {&#xA;        let time = startTime.split(&#x27;:&#x27;);&#xA;        if (time.length != 3) {&#xA;            message.reply(&#x27;Invalid start time&#x27;);&#xA;            return;&#xA;        }&#xA;        let h = parseInt(time[0]);&#xA;        let m = parseInt(time[1]);&#xA;        let s = parseInt(time[2]);&#xA;        if (isNaN(h) || isNaN(m) || isNaN(s)) {&#xA;            message.reply(&#x27;Invalid start time&#x27;);&#xA;            return;&#xA;        }&#xA;        startTime = `${h}:${m}:${s}`;&#xA;        options[&#x27;-ss&#x27;] = startTime;&#xA;        console.log("Start time: " &#x2B; startTime);&#xA;    }&#xA;&#xA;    await client.joinVoice(guildId, channelId);&#xA;    streamStatus.joined = true;&#xA;    streamStatus.playing = false;&#xA;    streamStatus.starttime = startTime ? startTime : "00:00:00";&#xA;    streamStatus.channelInfo = {&#xA;        guildId: guildId,&#xA;        channelId: channelId,&#xA;        cmdChannelId: message.channel.id&#xA;    }&#xA;    const streamUdpConn = await client.createStream();&#xA;    playVideo(movie.path, streamUdpConn, options);&#xA;    message.reply(&#x27;Playing &#x27; &#x2B; (startTime ? ` from ${startTime} ` : &#x27;&#x27;) &#x2B; moviename &#x2B; &#x27;...&#x27;);&#xA;    client.user?.setActivity(status_watch(moviename) as ActivityOptions);&#xA;}&#xA;&#xA;function stopCommand(message) {&#xA;    client.leaveVoice()&#xA;    streamStatus.joined = false;&#xA;    streamStatus.joinsucc = false;&#xA;    streamStatus.playing = false;&#xA;    streamStatus.channelInfo = {&#xA;        guildId: &#x27;&#x27;,&#xA;        channelId: &#x27;&#x27;,&#xA;        cmdChannelId: streamStatus.channelInfo.cmdChannelId&#xA;    }&#xA;    // use sigquit??&#xA;    command?.kill("SIGINT");&#xA;    // msg&#xA;    message.reply(&#x27;Stopped playing&#x27;);&#xA;    shouldStop = true;&#xA;    movList = [...originalMovList];&#xA;}&#xA;&#xA;function playtimeCommand(message) {&#xA;    // streamStatus.starttime &#x2B; streamStatus.timemark&#xA;    // starttime is hh:mm:ss, timemark is hh:mm:ss.000&#xA;    let start = streamStatus.starttime.split(&#x27;:&#x27;);&#xA;    let mark = streamStatus.timemark.split(&#x27;:&#x27;);&#xA;    let h = parseInt(start[0]) &#x2B; parseInt(mark[0]);&#xA;    let m = parseInt(start[1]) &#x2B; parseInt(mark[1]);&#xA;    let s = parseInt(start[2]) &#x2B; parseInt(mark[2]);&#xA;    if (s >= 60) {&#xA;        m &#x2B;= 1;&#xA;        s -= 60;&#xA;    }&#xA;    if (m >= 60) {&#xA;        h &#x2B;= 1;&#xA;        m -= 60;&#xA;    }&#xA;    message.reply(`Play time: ${h}:${m}:${s}`);&#xA;}&#xA;&#xA;function pauseCommand(message) {&#xA;    if (!streamStatus.playing) {&#xA;        command?.kill("SIGSTOP");&#xA;        message.reply(&#x27;Paused&#x27;);&#xA;        streamStatus.playing = false;&#xA;    } else {&#xA;        message.reply(&#x27;Not playing&#x27;);&#xA;    }&#xA;}&#xA;&#xA;function resumeCommand(message) {&#xA;    if (!streamStatus.playing) {&#xA;        command?.kill("SIGCONT");&#xA;        message.reply(&#x27;Resumed&#x27;);&#xA;        streamStatus.playing = true;&#xA;    } else {&#xA;        message.reply(&#x27;Not playing&#x27;);&#xA;    }&#xA;}&#xA;&#xA;function listCommand(message) {&#xA;    message.reply(`Available movies:\n${movies.map(m => m.name).join(&#x27;\n&#x27;)}`);&#xA;}&#xA;&#xA;function statusCommand(message) {&#xA;    message.reply(`Joined: ${streamStatus.joined}\nJoin success: ${streamStatus.joinsucc}\nPlaying: ${streamStatus.playing}\nChannel: ${streamStatus.channelInfo.guildId}/${streamStatus.channelInfo.channelId}\nTimemark: ${streamStatus.timemark}\nStart time: ${streamStatus.starttime}`);&#xA;}&#xA;&#xA;function refreshCommand(message) {&#xA;    // refresh movie list&#xA;    const movieFiles = fs.readdirSync(moviesFolder);&#xA;    movies = movieFiles.map(file => {&#xA;        const fileName = path.parse(file).name;&#xA;        // replace space with _&#xA;        return { name: fileName.replace(/ /g, &#x27;&#x27;), path: path.join(moviesFolder, file) };&#xA;    });&#xA;    message.reply(&#x27;Movie list refreshed &#x27; &#x2B; movies.length &#x2B; &#x27; movies found.\n&#x27; &#x2B; movies.map(m => m.name).join(&#x27;\n&#x27;));&#xA;}&#xA;&#xA;function helpCommand(message) {&#xA;    // reply all commands here&#xA;    message.reply(&#x27;Available commands:\nplay [guildId]/[channelId] [movie] [start time]\nstop\nlist\nstatus\nrefresh\nplaytime\npause\nresume\nhelp&#x27;);&#xA;}&#xA;&#xA;async function playVideo(video: string, udpConn: VoiceUdp, options: any) {&#xA;    console.log("Started playing video");&#xA;&#xA;    udpConn.voiceConnection.setSpeaking(true);&#xA;    udpConn.voiceConnection.setVideoStatus(true);&#xA;    try {&#xA;        let videoStream = streamLivestreamVideo(video, udpConn);&#xA;        command?.on(&#x27;progress&#x27;, (msg) => {&#xA;            // print timemark if it passed 10 second sionce last print, becareful when it pass 0&#xA;            if (streamStatus.timemark) {&#xA;                if (lastPrint != "") {&#xA;                    let last = lastPrint.split(&#x27;:&#x27;);&#xA;                    let now = msg.timemark.split(&#x27;:&#x27;);&#xA;                    // turn to seconds&#xA;                    let s = parseInt(now[2]) &#x2B; parseInt(now[1]) * 60 &#x2B; parseInt(now[0]) * 3600;&#xA;                    let l = parseInt(last[2]) &#x2B; parseInt(last[1]) * 60 &#x2B; parseInt(last[0]) * 3600;&#xA;                    if (s - l >= 10) {&#xA;                        console.log(`Timemark: ${msg.timemark}`);&#xA;                        lastPrint = msg.timemark;&#xA;                    }&#xA;                } else {&#xA;                    console.log(`Timemark: ${msg.timemark}`);&#xA;                    lastPrint = msg.timemark;&#xA;                }&#xA;            }&#xA;            streamStatus.timemark = msg.timemark;&#xA;        });&#xA;        const res = await videoStream;&#xA;        console.log("Finished playing video " &#x2B; res);&#xA;    } catch (e) {&#xA;        console.log(e);&#xA;    } finally {&#xA;        udpConn.voiceConnection.setSpeaking(false);&#xA;        udpConn.voiceConnection.setVideoStatus(false);&#xA;    }&#xA;    command?.kill("SIGINT");&#xA;    // send message to channel, not reply&#xA;    (client.channels.cache.get(streamStatus.channelInfo.cmdChannelId) as TextChannel).send(&#x27;Finished playing video, timemark is &#x27; &#x2B; streamStatus.timemark);&#xA;    client.leaveVoice();&#xA;    client.user?.setActivity(status_idle() as ActivityOptions)&#xA;    streamStatus.joined = false;&#xA;    streamStatus.joinsucc = false;&#xA;    streamStatus.playing = false;&#xA;    lastPrint = ""&#xA;    streamStatus.channelInfo = {&#xA;        guildId: &#x27;&#x27;,&#xA;        channelId: &#x27;&#x27;,&#xA;        cmdChannelId: &#x27;&#x27;&#xA;    }&#xA;}&#xA;&#xA;async function streamCommand(args, message) {&#xA;&#xA;    if (streamStatus.joined) {&#xA;        message.reply(&#x27;Already joined&#x27;);&#xA;        return;&#xA;    }&#xA;&#xA;    // args = [guildId]/[channelId]&#xA;    if (args.length == 0) {&#xA;        message.reply(&#x27;Missing voice channel&#x27;);&#xA;        return;&#xA;    }&#xA;&#xA;    // process args&#xA;    const [guildId, channelId] = args.shift()!.split(&#x27;/&#x27;);&#xA;    if (!guildId || !channelId) {&#xA;        message.reply(&#x27;Invalid voice channel&#x27;);&#xA;        return;&#xA;    }&#xA;&#xA;    let url = args.shift()&#xA;    let options = {}&#xA;&#xA;    await client.joinVoice(guildId, channelId);&#xA;    streamStatus.joined = true;&#xA;    streamStatus.playing = false;&#xA;    //streamStatus.starttime = startTime ? startTime : "00:00:00";&#xA;    streamStatus.channelInfo = {&#xA;        guildId: guildId,&#xA;        channelId: channelId,&#xA;        cmdChannelId: message.channel.id&#xA;    }&#xA;    const streamUdpConn = await client.createStream();&#xA;    playStream(url, streamUdpConn, options);&#xA;    message.reply(&#x27;Playing url&#x27;);&#xA;    client.user?.setActivity(status_watch(&#x27;livestream&#x27;) as ActivityOptions);&#xA;}&#xA;&#xA;async function playStream(video: string, udpConn: VoiceUdp, options: any) {&#xA;    console.log("Started playing video");&#xA;&#xA;    udpConn.voiceConnection.setSpeaking(true);&#xA;    udpConn.voiceConnection.setVideoStatus(true);&#xA;&#xA;    try {&#xA;        console.log("Trying to stream url");&#xA;        const res = await streamLivestreamVideo(video, udpConn);&#xA;        console.log("Finished streaming url");&#xA;    } catch (e) {&#xA;        console.log(e);&#xA;    } finally {&#xA;        udpConn.voiceConnection.setSpeaking(false);&#xA;        udpConn.voiceConnection.setVideoStatus(false);&#xA;    }&#xA;&#xA;    command?.kill("SIGINT");&#xA;    client.leaveVoice();&#xA;    client.user?.setActivity(status_idle() as ActivityOptions)&#xA;    streamStatus.joined = false;&#xA;    streamStatus.joinsucc = false;&#xA;    streamStatus.playing = false;&#xA;    streamStatus.channelInfo = {&#xA;        guildId: &#x27;&#x27;,&#xA;        channelId: &#x27;&#x27;,&#xA;        cmdChannelId: &#x27;&#x27;&#xA;    }&#xA;&#xA;}&#xA;&#xA;// run server if enabled in config&#xA;if (config.server.enabled) {&#xA;    // run server.js&#xA;    require(&#x27;./server&#x27;);&#xA;}&#xA;&#xA;

    &#xA;

    I've tried running the code with the nocache package, setting up a cron job to clean the cache every 5 minutes, unifying functions in the code, but nothigns works.&#xA;I think that the problem has to do with certain process that never really ends after one video finishes playing, probably ffmpeg. I don't know whether is my code, my vps or the library the problem.

    &#xA;

    I wanted the bot to stay in the voice channel streaming my videos 24/7 (no interruptions), I don't know how to prevent it from getting laggy after a while.

    &#xA;

    This is the config.json file just in case you wanna test the code and can't find it

    &#xA;

    {&#xA;    "token": "DCTOKEN",&#xA;    "videoChannels": ["ID", "OTHERID"],&#xA;    "commandChannels": ["ID", "OTHERID"],&#xA;    "adminIds": ["ID"],&#xA;    "movieFolder": "./movies/",&#xA;    "previewCache": "/tmp/preview-cache",&#xA;    "streamOpts": {&#xA;        "width": 1280,&#xA;        "height": 720,&#xA;        "fps": 30,&#xA;        "bitrateKbps": 3000,&#xA;        "hardware_acc": true&#xA;    },&#xA;    "server": {&#xA;        "enabled": false,&#xA;        "port": 8080&#xA;    }&#xA;}&#xA;&#xA;

    &#xA;