Recherche avancée

Médias (1)

Mot : - Tags -/publicité

Autres articles (94)

  • Amélioration de la version de base

    13 septembre 2013

    Jolie sélection multiple
    Le plugin Chosen permet d’améliorer l’ergonomie des champs de sélection multiple. Voir les deux images suivantes pour comparer.
    Il suffit pour cela d’activer le plugin Chosen (Configuration générale du site > Gestion des plugins), puis de configurer le plugin (Les squelettes > Chosen) en activant l’utilisation de Chosen dans le site public et en spécifiant les éléments de formulaires à améliorer, par exemple select[multiple] pour les listes à sélection multiple (...)

  • Les sons

    15 mai 2013, par
  • Gestion de la ferme

    2 mars 2010, par

    La ferme est gérée dans son ensemble par des "super admins".
    Certains réglages peuvent être fais afin de réguler les besoins des différents canaux.
    Dans un premier temps il utilise le plugin "Gestion de mutualisation"

Sur d’autres sites (5986)

  • Using Pipes for Stream Data in FFMPEG

    17 juillet 2024, par Aryan Kumar

    I am trying to input stream and decrease the bitrate of the video without saving it anywhere so i am hoping to pass it as a stream and get the output as a stream and send it to digital ocean spaces to get saved.
But I tried lots of things but my output Stream is getting empty. and the file is empty.

    


        public async Task VideoOperationAsync(Stream inputStream)
    {
        try
        {
            // Ensure the input stream is at the beginning
            inputStream.Position = 0;

            // Create a memory stream to hold the output data
            using (var outputStream = new MemoryStream())
            {
                var arguments = $"-i pipe:0 -f mp4 pipe:1";

                await Cli.Wrap("ffmpeg")
                    .WithArguments(arguments)
                    .WithStandardInputPipe(PipeSource.FromStream(inputStream))
                    .WithStandardOutputPipe(PipeTarget.ToStream(outputStream))
                    .WithValidation(CommandResultValidation.None)
                    .ExecuteAsync();

                // Ensure the output stream is at the beginning before reading
                outputStream.Position = 0;

                using (var fileStream = new FileStream(@"D:\Gremlin-data\VideoResized\output_cropped.mp4", FileMode.Create, FileAccess.Write))
                {
                    await outputStream.CopyToAsync(fileStream);
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"An error occurred: {ex.Message}");
            throw;  // Re-throw the exception if needed
        }
    }


    


    I also earlier tried this :

    


    public async Task VideoOperationAsync(Stream inputStream)

try

// Ensure the input stream is at the beginning
inputStream.Position = 0 ;

    


            var ffmpegProcess = new Process
        {
            StartInfo = new ProcessStartInfo
            {
                FileName = "ffmpeg",  // Ensure ffmpeg is in your PATH or provide the full path
                Arguments = $"-i pipe:0 -b:v 2000k -f mp4 pipe:1",  // Correct bitrate format
                RedirectStandardInput = true,
                RedirectStandardOutput = true,
                RedirectStandardError = true,  // Capture standard error
                UseShellExecute = false,
                CreateNoWindow = true
            }
        };

        ffmpegProcess.Start();

        // Write input stream to ffmpeg's standard input asynchronously
        Task writingTask = Task.Run(async () =>
        {
            await inputStream.CopyToAsync(ffmpegProcess.StandardInput.BaseStream);
            ffmpegProcess.StandardInput.BaseStream.Close();
        });

        // Read ffmpeg's standard output to a memory stream asynchronously
        using (MemoryStream ms = new MemoryStream())
        {
            Task readingTask = Task.Run(async () =>
            {
                await ffmpegProcess.StandardOutput.BaseStream.CopyToAsync(ms);
            });


    


  • Display real time frames from several RTSP streams

    13 février 2024, par Mrax

    I have this class, it uses ffmpeg library for rtsp live streaming :

    


    #include <iostream>&#xA;#include <string>&#xA;#include <vector>&#xA;#include <mutex>&#xA;&#xA;extern "C"&#xA;{&#xA;#include <libavcodec></libavcodec>avcodec.h>&#xA;#include <libavformat></libavformat>avformat.h>&#xA;#include <libavformat></libavformat>avio.h>&#xA;}&#xA;&#xA;class ryMediaSource&#xA;{&#xA;public:&#xA;    ryMediaSource() {}&#xA;    ryMediaSource(const ryMediaSource&amp; other);&#xA;    ~ryMediaSource();&#xA;&#xA;    bool ryOpenMediaSource(const std::string&amp;);&#xA;&#xA;private:&#xA;    mediaSource pMediaSource;&#xA;    AVFormatContext* pFormatCtx;&#xA;    mutable std::mutex pMutex;&#xA;};&#xA;</mutex></vector></string></iostream>

    &#xA;

    And inside my main file, I have these vector of ryMediaSource and four rstp urls :

    &#xA;

    std::vector<rymediasource> mediaSources;&#xA;std::vector streams =&#xA;{&#xA;    {"rtsp://1&#xA;    {"rtsp://2&#xA;    {"rtsp://3&#xA;    {"rtsp://4&#xA;};&#xA;</rymediasource>

    &#xA;

    Creating a instance for every vector :

    &#xA;

    for (const auto&amp; stream : streams)&#xA;{&#xA;    mediaSources.emplace_back(); // Create a new instance for each stream&#xA;}&#xA;

    &#xA;

    And opening all the streams (I need to have access to all the streams, all the time).

    &#xA;

    for (size_t s = 0; s &lt; streams.size(); s&#x2B;&#x2B;)&#xA;{&#xA;     mediaSources[s].ryOpenMediaSource(streams[s]);&#xA;}&#xA;

    &#xA;

    After all the streams are loaded, I start to display the videos all of the streams : av_read_frame(pFormatCtx, pPacket).&#xA;But I am having a gap from what is been displayed to what is really capturing from the source (IP Cameras).&#xA;From ryOpenMediaSource(streams[0]) is about 11 seconds, ryOpenMediaSource(streams[1]) about 7 seconds, ryOpenMediaSource(streams[2]) is about 4 seconds and ryOpenMediaSource(streams[3]) is real time.&#xA;I realized that the issue is on my ryOpenMediaSource code :

    &#xA;

    bool ryMediaSource::ryOpenMediaSource(const std::string&amp; url)&#xA;{&#xA;    int rc = -1;&#xA;&#xA;    pFormatCtx = avformat_alloc_context();&#xA;    if (!pFormatCtx)&#xA;        throw std::runtime_error("Failed to allocate AVFormatContext.");&#xA;    rc = avformat_open_input(&amp;pFormatCtx, url.c_str(), NULL, NULL);&#xA;    if (rc &lt; 0)&#xA;    {&#xA;        return false;&#xA;    }&#xA;}&#xA;

    &#xA;

    My question is, why this is happening ? Why can't all streams have the same (time stamp ?) , as the last inserted in my vector of ryMediaSource ?

    &#xA;

    Should I overwrite some variable of pFormatCtx to "force" the all vector to have the (time stamp ?) as the last one ? If so, can you give me some guidance ?

    &#xA;

    Tried setting some different values on pFormatCtx after loaded with avformat_open_input(&pFormatCtx, url.c_str(), NULL, &pDicts) ; but no luck at all.

    &#xA;

    I am expecting that all streams started at the same time, even if pre loading them, for later on, transform these frames into a cv::Mat for rendering.

    &#xA;

    MRE :

    &#xA;

    Header :&#xA;&#xA;#pragma once&#xA;&#xA;#include <iostream>&#xA;#include <string>&#xA;#include <vector>&#xA;#include <chrono>&#xA;#include <thread>&#xA;#include <mutex>&#xA;&#xA;&#xA;extern "C"&#xA;{&#xA;#include <libavcodec></libavcodec>avcodec.h>&#xA;#include <libavformat></libavformat>avformat.h>&#xA;#include <libavutil></libavutil>pixdesc.h>&#xA;#include <libavutil></libavutil>hwcontext.h>&#xA;#include <libavutil></libavutil>opt.h>&#xA;#include <libavutil></libavutil>avassert.h>&#xA;#include <libavutil></libavutil>imgutils.h>&#xA;#include <libswscale></libswscale>swscale.h>&#xA;#include <libavdevice></libavdevice>avdevice.h>&#xA;#include <libavformat></libavformat>avio.h>&#xA;#include <libavutil></libavutil>time.h>&#xA;}&#xA;&#xA;class ryMediaSource&#xA;{&#xA;public:&#xA;    ryMediaSource() {}&#xA;    ryMediaSource(const ryMediaSource&amp; other);&#xA;    ~ryMediaSource();&#xA;&#xA;    struct mediaSourceParams&#xA;    {&#xA;        int sx;&#xA;        int sy;&#xA;        int lsize;&#xA;        double fps;&#xA;        unsigned char* frame;&#xA;    };&#xA;&#xA;    bool ryOpenMediaSource(const std::string&amp;);&#xA;    mediaSourceParams ryGetMediaSourceFrame();&#xA;    void ryCloseMediaSource();&#xA;&#xA;private:&#xA;    mediaSource pMediaSource;&#xA;    AVFormatContext* pFormatCtx;&#xA;    AVCodecContext* pCodecCtx;&#xA;    AVFrame* pFrame;&#xA;    SwsContext* pSwsCtx;&#xA;    AVPacket* pPacket;&#xA;    int pVideoStream;&#xA;    uint8_t* pBuffer;&#xA;    AVFrame* pPict;&#xA;    double pFPS;&#xA;    mutable std::mutex pMutex;&#xA;};&#xA;&#xA;C&#x2B;&#x2B; source code :&#xA;&#xA;#include "ryMediaSource.hpp"&#xA;&#xA;ryMediaSource::ryMediaSource(const ryMediaSource&amp; other)&#xA;:pFormatCtx(nullptr), &#xA;pCodecCtx(nullptr), &#xA;pFrame(nullptr), &#xA;pSwsCtx(nullptr), &#xA;pPacket(nullptr), &#xA;pBuffer(nullptr), &#xA;pPict(nullptr)&#xA;{&#xA;    std::lock_guard lock(other.pMutex);&#xA;    av_log_set_level(0);&#xA;    avformat_network_init();&#xA;}&#xA;&#xA;bool ryMediaSource::ryOpenMediaSource(const std::string&amp; url)&#xA;{&#xA;    int rc = -1;&#xA;&#xA;    try&#xA;    {&#xA;        AVDictionary* pDicts = nullptr;&#xA;&#xA;        pFormatCtx = avformat_alloc_context();&#xA;        if (!pFormatCtx)&#xA;            throw std::runtime_error("Failed to allocate AVFormatContext.");&#xA;        rc = av_dict_set(&amp;pDicts, "rtsp_transport", "tcp", 0);&#xA;        if (rc &lt; 0)&#xA;            throw std::runtime_error("av_dict_set failed.");&#xA;                rc = avformat_open_input(&amp;pFormatCtx, url.c_str(), NULL, &amp;pDicts);&#xA;        if (rc &lt; 0)&#xA;        {&#xA;            av_dict_free(&amp;pDicts);  // Free the dictionary in case of an error&#xA;            throw std::runtime_error("Could not open source.");&#xA;        }&#xA;    }&#xA;    catch (const std::exception&amp; e)&#xA;    {&#xA;        std::cerr &lt;&lt; "Exception: " &lt;&lt; e.what() &lt;&lt; std::endl;&#xA;        return false;&#xA;    }&#xA;&#xA;    try&#xA;    {&#xA;        rc = avformat_find_stream_info(pFormatCtx, NULL);&#xA;        if (rc &lt; 0)&#xA;        {&#xA;            throw std::runtime_error("Could not find stream information.");&#xA;        }&#xA;        pVideoStream = -1;&#xA;        for (size_t v = 0; v &lt; pFormatCtx->nb_streams; &#x2B;&#x2B;v)&#xA;        {&#xA;            if (pFormatCtx->streams[v]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)&#xA;            {&#xA;                pVideoStream = static_cast<int>(v);&#xA;                AVRational rational = pFormatCtx->streams[pVideoStream]->avg_frame_rate;&#xA;                pFPS = 1.0 / ((double)rational.num / (double)(rational.den));&#xA;                break;&#xA;            }&#xA;        }&#xA;        if (pVideoStream &lt; 0)&#xA;        {&#xA;            throw std::runtime_error("Could not find video stream.");&#xA;        }&#xA;&#xA;        const AVCodec* pCodec = avcodec_find_decoder(pFormatCtx->streams[pVideoStream]->codecpar->codec_id);&#xA;        if (!pCodec)&#xA;        {&#xA;            throw std::runtime_error("Unsupported codec!");&#xA;        }&#xA;        pCodecCtx = avcodec_alloc_context3(pCodec);&#xA;        if (!pCodecCtx)&#xA;        {&#xA;            throw std::runtime_error("Failed to allocate AVCodecContext.");&#xA;        }&#xA;        rc = avcodec_parameters_to_context(pCodecCtx, pFormatCtx->streams[pVideoStream]->codecpar);&#xA;        if (rc != 0)&#xA;        {&#xA;            throw std::runtime_error("Could not copy codec context.");&#xA;        }&#xA;        rc = avcodec_open2(pCodecCtx, pCodec, NULL);&#xA;        if (rc &lt; 0)&#xA;        {&#xA;            throw std::runtime_error("Could not open codec.");&#xA;        }&#xA;        pFrame = av_frame_alloc();&#xA;        if (!pFrame)&#xA;        {&#xA;            throw std::runtime_error("Could not allocate frame.");&#xA;        }&#xA;        pSwsCtx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_BGR24, SWS_BILINEAR, NULL, NULL, NULL);&#xA;        if (!pSwsCtx)&#xA;        {&#xA;            throw std::runtime_error("Failed to allocate SwsContext.");&#xA;        }&#xA;        pPacket = av_packet_alloc();&#xA;        if (!pPacket)&#xA;        {&#xA;            throw std::runtime_error("Could not allocate AVPacket.");&#xA;        }&#xA;        pBuffer = (uint8_t*)av_malloc(av_image_get_buffer_size(AV_PIX_FMT_BGR24, pCodecCtx->width, pCodecCtx->height, 1));&#xA;        if (!pBuffer)&#xA;        {&#xA;            throw std::runtime_error("Could not allocate buffer.");&#xA;        }&#xA;        pPict = av_frame_alloc();&#xA;        if (!pPict)&#xA;        {&#xA;            throw std::runtime_error("Could not allocate frame.");&#xA;        }&#xA;        av_image_fill_arrays(pPict->data, pPict->linesize, pBuffer, AV_PIX_FMT_BGR24, pCodecCtx->width, pCodecCtx->height, 1);&#xA;    }&#xA;    catch (const std::exception&amp; e)&#xA;    {&#xA;        std::cerr &lt;&lt; "Exception: " &lt;&lt; e.what() &lt;&lt; std::endl;&#xA;        return false;&#xA;    }&#xA;&#xA;    return true;&#xA;}&#xA;&#xA;ryMediaSource::mediaSourceParams ryMediaSource::ryGetMediaSourceFrame()&#xA;{&#xA;    mediaSourceParams msp = { 0, 0, 0, 0.0, nullptr };&#xA;    char errbuf[AV_ERROR_MAX_STRING_SIZE];&#xA;&#xA;    std::lock_guard lock(pMutex);&#xA;    if (av_read_frame(pFormatCtx, pPacket) >= 0)&#xA;    {&#xA;        if (pPacket->stream_index == pVideoStream)&#xA;        {&#xA;            int ret = avcodec_send_packet(pCodecCtx, pPacket);&#xA;            if (ret &lt; 0)&#xA;            {&#xA;                av_strerror(ret, errbuf, sizeof(errbuf));&#xA;                std::cerr &lt;&lt; "Error sending packet for avcodec_send_packet: " &lt;&lt; errbuf &lt;&lt; std::endl;&#xA;&#xA;                std::cerr &lt;&lt; "avcodec_flush_buffers " &lt;&lt; errbuf &lt;&lt; std::endl;&#xA;                avcodec_flush_buffers(pCodecCtx);&#xA;                // Handle specific error cases&#xA;                if (ret == AVERROR(EAGAIN))&#xA;                {&#xA;                    std::cerr &lt;&lt; "EAGAIN indicates that more input is required" &lt;&lt; std::endl;&#xA;                }&#xA;                else if (ret == AVERROR_EOF)&#xA;                {&#xA;                    std::cerr &lt;&lt; "AVERROR_EOF indicates that the encoder has been fully flushed" &lt;&lt; std::endl;&#xA;                }&#xA;                else&#xA;                {&#xA;                    //std::cerr &lt;&lt; "avcodec_flush_buffers " &lt;&lt; errbuf &lt;&lt; std::endl;&#xA;                    // For other errors, you may choose to flush the codec context and continue decoding.&#xA;                    //avcodec_flush_buffers(pCodecCtx);&#xA;                }&#xA;            }&#xA;            ret = avcodec_receive_frame(pCodecCtx, pFrame);&#xA;            if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)&#xA;            {&#xA;                av_strerror(ret, errbuf, sizeof(errbuf));&#xA;&#xA;                std::cerr &lt;&lt; "Error receiving packet for avcodec_receive_frame: " &lt;&lt; errbuf &lt;&lt; std::endl;&#xA;&#xA;&#xA;                // EAGAIN indicates that more frames are needed or EOF is reached.&#xA;                // You may choose to break out of the loop or handle it based on your application&#x27;s logic.&#xA;&#xA;                return msp;&#xA;            }&#xA;            else if (ret &lt; 0)&#xA;            {&#xA;                av_strerror(ret, errbuf, sizeof(errbuf));&#xA;                std::cerr &lt;&lt; "Error receiving frame for avcodec_receive_frame: " &lt;&lt; errbuf &lt;&lt; std::endl;&#xA;                // Optionally, handle specific error cases&#xA;                if (ret == AVERROR(EINVAL))&#xA;                {&#xA;                    std::cerr &lt;&lt; "EINVAL indicates that more input is required" &lt;&lt; std::endl;&#xA;&#xA;                    //break;&#xA;                }&#xA;                else&#xA;                {&#xA;                    std::cerr &lt;&lt; "For other errors" &lt;&lt; std::endl;&#xA;&#xA;                    //break;&#xA;                }&#xA;            }&#xA;            // Move memory allocation outside the loop if frame size is constant&#xA;            size_t bufferSize = static_cast(pPict->linesize[0]) * pCodecCtx->height;&#xA;            msp.frame = new unsigned char[bufferSize];&#xA;            msp.lsize = pPict->linesize[0];&#xA;            msp.sx = pCodecCtx->width;&#xA;            msp.sy = pCodecCtx->height;&#xA;            msp.fps = pFPS;&#xA;            sws_scale(pSwsCtx, (uint8_t const* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pPict->data, pPict->linesize);&#xA;            std::memcpy(msp.frame, pBuffer, bufferSize);&#xA;            //delete[] msp.frame;&#xA;        }&#xA;&#xA;        // Unref packet for non-video streams&#xA;        av_packet_unref(pPacket);&#xA;    }&#xA;&#xA;    return msp;&#xA;}&#xA;&#xA;main.cpp&#xA;&#xA;std::vector streams =&#xA;{&#xA;    {"rtsp://1},&#xA;    {"rtsp://2},&#xA;    {"rtsp://3},&#xA;    {"rtsp://4},&#xA;};&#xA;&#xA;std::vector<rymediasource> mediaSources;&#xA;&#xA;void main()&#xA;{&#xA;    int key = 0;&#xA;    int channel = 0;&#xA;    std::vector streamFrame(streams.size());&#xA;    ryMediaSource::mediaSourceParams msp = { 0, 0, 0, 0.0, nullptr };&#xA;&#xA;    for (const auto&amp; stream : streams)&#xA;    {&#xA;        mediaSources.emplace_back(); // Create a new instance for each stream&#xA;    }&#xA;    for (size_t s = 0; s &lt; streams.size(); s&#x2B;&#x2B;)&#xA;    {&#xA;        try&#xA;        {&#xA;            mediaSources[s].ryOpenMediaSource(streams[s]);&#xA;        }&#xA;        catch (const std::exception&amp; e)&#xA;        {&#xA;            std::cerr &lt;&lt; "Error initializing stream " &lt;&lt; s &lt;&lt; ": " &lt;&lt; e.what() &lt;&lt; std::endl;&#xA;        }&#xA;    }&#xA;&#xA;    cv::namedWindow("ryInferenceServer", cv::WINDOW_FREERATIO);&#xA;    cv::resizeWindow("ryInferenceServer", 640, 480);&#xA;    cv::moveWindow("ryInferenceServer", 0, 0);&#xA;    for (;;)&#xA;    {&#xA;        for (size_t st = 0; st &lt; mediaSources.size(); &#x2B;&#x2B;st)&#xA;        {&#xA;            msp = mediaSources[st].ryGetMediaSourceFrame();&#xA;            if (msp.frame != nullptr)&#xA;            {&#xA;                cv::Mat preview;&#xA;                cv::Mat frame(msp.sy, msp.sx, CV_8UC3, msp.frame, msp.lsize);&#xA;                cv::resize(frame, preview, cv::Size(640, 480));&#xA;                if (!frame.empty())&#xA;                {&#xA;                    try&#xA;                    {&#xA;                        streamFrame[st] = frame.clone();&#xA;                        if (channel == st)&#xA;                        {&#xA;                            cv::imshow("ryInferenceServer", preview);&#xA;                            key = cv::waitKeyEx(1);&#xA;                            if (key == LEFT_KEY)&#xA;                            {&#xA;                                channel--;&#xA;                                if (channel &lt; 0)&#xA;                                    channel = 0;&#xA;                            }&#xA;                            if (key == RIGHT_KEY)&#xA;                            {&#xA;                                channel&#x2B;&#x2B;;&#xA;                                if (channel >= mediaSources.size())&#xA;                                    channel = mediaSources.size() - 1;&#xA;                            }&#xA;                            if (key == 27)&#xA;                                break;&#xA;                        }&#xA;                        streamFrame[st].release();&#xA;                        delete[] msp.frame;&#xA;                    }&#xA;                    catch (const std::exception&amp; e)&#xA;                    {&#xA;                        std::cerr &lt;&lt; "Exception in processing frame for stream " &lt;&lt; st &lt;&lt; ": " &lt;&lt; e.what() &lt;&lt; std::endl;&#xA;                    }&#xA;                }&#xA;                frame.release();&#xA;            }&#xA;        }&#xA;    }&#xA;}&#xA;</rymediasource></int></mutex></thread></chrono></vector></string></iostream>

    &#xA;

  • Why are the colors transposed in my webm thumbnails ?

    9 décembre 2022, par Peter Chaplin

    I have been using ffmpeg to generate webm files from png frames, and the webm files run ok in my video player, but the thumbnail colours appear transposed - blue replacing red, purple replacing orange, brown replacing green. I've also encountered issue uploading the webm to an image hosting site (which normally does support webms), though this might be an issue on their end.&#xA;I'm on Ubuntu 22.04.1 LTS

    &#xA;

    Does anyone know what might be causing this, and how to fix it ? Or how to check whether the webm files are ok or corrupted ?

    &#xA;

    *Edit : ok, here's a side-by-side comparison of the thumbnails that appear in my file explorer - mp4 on the left and webm on the right.&#xA;Both were generated from the same set of pngs, using the same command except with the filename extension changed.

    &#xA;

    screencap of thumbnails

    &#xA;

    Specifically,

    &#xA;

    ffmpeg -framerate 24 -i Panel2Humanized/frame%04d.png panel2humanskin.webm&#xA;

    &#xA;

    and

    &#xA;

    ffmpeg -framerate 24 -i Panel2Humanized/frame%04d.png panel2humanskin.mp4&#xA;

    &#xA;

    Both look the same when opened with a video player. It looks like the mp4 thumbnail grabbed the 1st frame while the webm grabbed the last, but the colors should be the same in each. (The text-bubble in the top-left is yellow in the mp4).

    &#xA;

    *Follow-up : Apparently my WebMs are being generated in GBRP (Green-Blue-Red Planar) pixel format, the site I was trying to upload to requires YUV420P (Luma/Chroma 4:2:0 Planar) format, maybe that's the issue ? I'm still not sure exactly what that means or how to fix it.

    &#xA;

    *Final follow-up : Looks like I needed to change the argument to :

    &#xA;

    ffmpeg -framerate 24 -i Panel2Humanized/frame%04d.png -pix_fmt yuv420p paned2humanskin.webm&#xA;

    &#xA;