Recherche avancée

Médias (0)

Mot : - Tags -/serveur

Aucun média correspondant à vos critères n’est disponible sur le site.

Autres articles (19)

  • Ajouter notes et légendes aux images

    7 février 2011, par

    Pour pouvoir ajouter notes et légendes aux images, la première étape est d’installer le plugin "Légendes".
    Une fois le plugin activé, vous pouvez le configurer dans l’espace de configuration afin de modifier les droits de création / modification et de suppression des notes. Par défaut seuls les administrateurs du site peuvent ajouter des notes aux images.
    Modification lors de l’ajout d’un média
    Lors de l’ajout d’un média de type "image" un nouveau bouton apparait au dessus de la prévisualisation (...)

  • ANNEXE : Les plugins utilisés spécifiquement pour la ferme

    5 mars 2010, par

    Le site central/maître de la ferme a besoin d’utiliser plusieurs plugins supplémentaires vis à vis des canaux pour son bon fonctionnement. le plugin Gestion de la mutualisation ; le plugin inscription3 pour gérer les inscriptions et les demandes de création d’instance de mutualisation dès l’inscription des utilisateurs ; le plugin verifier qui fournit une API de vérification des champs (utilisé par inscription3) ; le plugin champs extras v2 nécessité par inscription3 (...)

  • Selection of projects using MediaSPIP

    2 mai 2011, par

    The examples below are representative elements of MediaSPIP specific uses for specific projects.
    MediaSPIP farm @ Infini
    The non profit organizationInfini develops hospitality activities, internet access point, training, realizing innovative projects in the field of information and communication technologies and Communication, and hosting of websites. It plays a unique and prominent role in the Brest (France) area, at the national level, among the half-dozen such association. Its members (...)

Sur d’autres sites (4500)

  • 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;

  • CRO Audit : Increase Your Conversions in 10 Simple Steps

    25 mars 2024, par Erin

    You have two options if you’re unhappy with your website’s conversion rates.

    The first is to implement a couple of random tactics you heard on that marketing podcast, which worked for a business completely unrelated to yours. 

    The other is to take a more systematic, measured approach. An approach that finds specific problems with the pages on your site and fixes them one by one. 

    You’re choosing the second option, right ?

    Good, then let’s explain what a conversion rate optimisation audit is and how you can complete one using our step-by-step process.

    What is a CRO audit ?

    A conversion rate optimisation audit (CRO audit) systematically evaluates your website. It identifies opportunities to enhance your website’s performance and improve conversion rates. 

    During the audit, you’ll analyse your website’s entire customer journey, collect valuable user behaviour data and cross reference that with web analytics to find site elements (forms, calls-to-actions, etc.) that you can optimise.

    What is a CRO audit

    It’s one (and usually the first) part of a wider CRO strategy. 

    For example, an online retailer might run a CRO audit to discover why cart abandonment rates are high. The audit may throw up several potential problems (like a confusing checkout form and poor navigation), which the retailer can then spend time optimising using A/B tests

    Why run a CRO audit ?

    A CRO audit can be a lot of work, but it’s well worth the effort. Here are the benefits you can expect from running one.

    Generate targeted and relevant insights

    You’ve probably already tested some “best practice” conversion rate optimisations, like changing the colour of your CTA button, adding social proof or highlighting benefits to your headlines. 

    These are great, but they aren’t tailored to your audience. Running a CRO audit will ensure you find (and rectify) the conversion bottlenecks and barriers that impact your users, not someone else’s.

    Improve conversion rates

    Ultimately, CRO audits are about improving conversion rates and increasing revenue. Finding and eliminating barriers to conversion makes it much more likely that users will convert. 

    But that’s not all. CRO audits also improve the user experience and customer satisfaction. The audit process will help you understand how users behave on your website, allowing you to create a more user-friendly customer experience. 

    A 10-step process for running your first CRO audit 

    Want to conduct your first CRO audit ? Follow the ten-step process we outline below :

    A 10-step process for running your first CRO audit

    1. Define your goals

    Start your CRO audit by setting conversion goals that marry with the wider goals of your business. The more clearly you define your goals, the easier it will be to evaluate your website for opportunities. 

    Your goals could include :

    • Booking more trials
    • Getting more email subscribers
    • Reducing cart abandonments

    You should also define the specific actions users need to take for you to achieve these goals. For example, users will have to click on your call-to-action and complete a form to book more trials. On the other hand, reducing cart abandonments requires users to add items to their cart and click through all of the forms during the checkout process. 

    If you’re unsure where to start, we recommend reading our CRO statistics roundup to see how your site compares to industry averages for metrics like conversion and click-through rates. 

    You’ll also want to ensure you track these conversion goals in your web analytics software. In Matomo, it only takes a few minutes to set up a new conversion goal, and the goals dashboard makes it easy to see your performance at a glance. 

    Try Matomo for Free

    Get the web insights you need, without compromising data accuracy.

    No credit card required

    2. Review your analytics

    With your goals in mind, the next step is to dive into your website analytics and identify pages that need improvement.

    Consider the following conversion metrics when analysing pages :

    • Conversion rate
    • Average time on page
    • Average order value
    • Click-through rate

    Ensure you’re analysing metrics aligning with the goals you set in step one. Average order value could be a great metric to track if you want to reduce cart abandonments, for example, but it’s unsuitable to get more email subscribers.

    3. Research the user experience

    Next, you’ll want to gather user experience data to better understand how potential customers use your website and why they aren’t converting as often as you’d like. 

    You can use several tools for user behaviour analysis, but we recommend heatmaps and session recordings.

    Heatmaps visually represent how users click, move and scroll your website. It will show where visitors place their attention and which page elements are ignored. 

    Take a look at this example below from our website. As you can see, the navigation, headline and CTA get the most attention. If we weren’t seeing as many conversions as we liked and our CTAs were getting ignored, that might be a sign to change their colour or placement. 

    Screenshot of Matomo heatmap feature

    Session recordings capture the actions users take as they browse your website. They let you watch a video playback of how visitors behave, capturing clicks and scrolls so you can see each visitor’s steps in order. 

    Session recordings will show you how users navigate and where they drop off. 

    4. Analyse your forms

    Whether your forms are too confusing or too long, there are plenty of reasons for users to abandon your forms. 

    But how many forms are they abandoning exactly and which forms are there ?

    That’s what form analysis is for. 

    Running a form analysis will highlight which forms need work and reveal whether forms could be contributing to a page’s poor conversion rate. It’s how Concrete CMS tripled its leads in just a few days.

    Matomo’s Form Analytics feature makes running form analysis easy.

    A screenshot of Matomo's form analysis dashboard

    Just open up the forms dashboard to get a snapshot of your forms’ key metrics, including average hesitation time, starter rate and submission rates. 

    Try Matomo for Free

    Get the web insights you need, without compromising data accuracy.

    No credit card required

    5. Analyse your conversion funnel

    Next, analyse the conversion funnel to see if there’s an obvious bottleneck or several pages where visitors abandon your desired action. Common conversion abandonment points are shopping carts and forms.

    A website conversion funnel

    For example, you could find there is a drop-off in conversions between checking out and making a purchase or between booking a demo and signing up for a subscription. Understanding where these drop-offs occur lets you dig deeper and make targeted improvements.

    Don’t worry if you’ve got a very long funnel. Start at the bottom and work backward. Problems with the pages at the very end of your funnel tasked with converting customers (landing pages, checkout pages, etc.) will have the biggest impact on your conversion rate. So, it makes sense to start there. 

    6. Analyse campaigns and traffic sources (marketing attribution)

    It’s now time to analyse traffic quality to ensure you’re powering your conversion optimisation efforts with the best traffic possible. 

    This can also help you find your best customers so you can focus on acquiring more of them and tailoring your optimisation efforts to their preferences. 

    Run a marketing attribution report to see which traffic sources generate the most conversions and have the highest conversion rates. 

    Matomo comparing linear, first click, and last click attribution models in the marketing attribution dashboard

    Using marketing attribution is crucial here because it gives a fuller picture of how customers move through their journey, recognising the impact of various touchpoints in making a decision, unlike last-click attribution, which only credits the final touchpoint before a conversion.

    7. Use surveys and other qualitative data sources

    Increase the amount of qualitative data you have access to by speaking directly to customers. Surveys, interviews and other user feedback methods add depth and context to your user behaviour research.

    Sure, you aren’t getting feedback from hundreds of customers like you do with heatmaps or session recordings, but the information can sometimes be much richer. Users will often tell you outright why they didn’t take a specific action in a survey response (or what convinced them to convert). 

    Running surveys is now even easier in Matomo, thanks to the Matomo Surveys third-party plugin. This lets you add a customisable survey popup to your site, the data from which is automatically added to Matomo and can be combined with Matomo segments.

    8. Develop a conversion hypothesis

    Using all of the insights you’ve gathered up to this point, you can now hypothesise what’s wrong and how you can fix it. 

    Here’s a template you can use :

    Conversion Hypothesis Template

    This could end up looking something like the following :

    Based on evidence gathered from web analytics and heatmaps, moving our signup form above the fold will fix our lack of free trial signups, improving signups by 50%.

    A hypothesis recorded in Matomo

    Make sure you write your hypothesis down somewhere. Matomo lets you document your hypothesis when creating an A/B test, so it’s easy to reflect on when the test finishes. 

    9. Run A/B tests

    Now, it’s time to put your theory into practice by running an A/B test.

    Create an experiment using a platform like Matomo that creates two different versions of your page : the original and one with the change you mentioned in your hypothesis. 

    There’s no set time for you to run an A/B test. Just keep running it until the outcome is statistically significant. This is something your A/B testing platform should do automatically. 

    A statistically significant result means it would be very unlikely the outcome doesn’t happen in the long term.

    A screenshot of an A/B test

    As you can see in the image above, the wide header variation has significantly outperformed both the original and the other variation. So we can be pretty confident about making the change permanent. 

    If the outcome of your A/B test also validates your conversion hypothesis, you can implement the change. If not, analyse the data, brainstorm another hypothesis and run another A/B test. 

    Try Matomo for Free

    Get the web insights you need, without compromising data accuracy.

    No credit card required

    10. Monitor and iterate

    You need to develop a culture of continuous improvement to succeed with conversion rate optimisation. That means constantly monitoring your conversion goals and running tests to improve your metrics. 

    While you don’t need to run a conversion audit every month, you should run audits regularly throughout the year.

    How often should you conduct a CRO audit ? 

    You should conduct a CRO audit fairly regularly. 

    We recommend creating a CRO schedule that sees you run a CRO audit every six to 12 months. That will ensure you continue identifying problem pages and keeping your conversion rates competitive. 

    Regular CRO audits will also account for evolving consumer behaviours, changes in your industry and your own business goals, all of which can impact your approach conversion rate optimisation. 

    Run your CRO audit with Matomo

    A CRO audit process is the only way you can identify conversion optimisation methods that will work for your site and your target audience. It’s a methodical, data-backed strategy for making targeted improvements to send conversion rates soaring. 

    There are a lot of steps to complete, but you don’t need dozens of tools to run a CRO audit process. 

    Just one : Matomo.

    Unlike other web analytics platforms, like Google Analytics, Matomo has the built-in tools and plugins to help with every step of the CRO audit process, from web analytics to conversion funnel analysis and A/B testing. With its accurate, unsampled data and privacy-friendly tracking, Matomo is the ideal choice for optimising conversions. 

    Learn how to increase your conversions with Matomo, and start a free 21-day trial today. No credit card required.

  • What Is Incrementality & Why Is It Important in Marketing ?

    26 mars 2024, par Erin

    Imagine this : you just launched your latest campaign and it was a major success.

    You blew last month’s results out of the water.

    You combined a variety of tactics, channels and ad creatives to make it work.

    Now, it’s time to build the next campaign.

    The only issue ?

    You don’t know what made it successful or how much your recent efforts impacted the results.

    You’ve been building your brand for years. You’ve built up a variety of marketing pillars that are working for you. So, how do you know how much of your campaign is from years of effort or a new tactic you just implemented ?

    The key is incrementality.

    This is a way to properly attribute the right weight to your marketing tactics.

    In this article, we break down what incrementality is in marketing, how it differs from traditional attribution and how you can calculate and track it to grow your business.

    What is incrementality in marketing ?

    Incrementality in marketing is growth that can be directly credited to a marketing effort above and beyond the success of the branding.

    It looks at how much a specific tactic positively impacted a campaign on top of overall branding and marketing strategies.

    What is incrementally in marketing?

    For example, this could be how much a specific tactic, campaign or channel helped increase conversions, email sign-ups or organic traffic.

    The primary purpose of incrementally in marketing is to more accurately determine the impact a single marketing variable had on the success of a project.

    It removes every other factor and isolates the specific method to help marketers double down on that strategy or move on to new tactics.

    With Matomo, you can track conversions simply. With our last non-direct channel attribution system, you’ll be able to quickly see what channels are converting (and which aren’t) so you can gain insights into incrementality. 

    See why over 1 million websites choose Matomo today.

    Try Matomo for Free

    Get the web insights you need, without compromising data accuracy.

    No credit card required

    How incrementality differs from attribution

    In marketing and advertising, it’s crucial to understand what tactics and activities drive growth.

    Incrementality and attribution help marketers and business owners understand what efforts impact their results.

    But they’re not the same.

    Here’s how they differ :

    Incrementality vs. attribution

    Incrementality explained

    Incrementality measures how much a specific marketing campaign or activity drives additional sales or growth.

    Simply put, it’s analysing the difference between having never implemented the campaign (or tactic or channel) in the first place versus the impact of the activity.

    In other words, how much revenue would you have generated this month without campaign A ?

    And how much additional revenue did you generate directly due to campaign A ?

    The reality is that dozens of factors impact revenue and growth.

    You aren’t just pouring your marketing into one specific channel or campaign at a time.

    Chances are, you’ve got your hands on several marketing initiatives like SEO, PPC, organic social media, paid search, email marketing and more.

    Beyond that, you’ve built a brand with a not-so-tangible impact on your recurring revenue.

    So, the question is, if you took away your new campaign, would you still be generating the same amount of revenue ?

    And, if you add in that campaign, how much additional revenue and growth did it directly create ?

    That is incrementality. It’s how much a campaign went above and beyond to add new revenue that wouldn’t have been there otherwise.

    So, how does attribution play into all of this ?

    Attribution explained

    Attribution is simply the process of assigning credit for a conversion to a particular marketing touchpoint.

    While incrementality is about narrowing down the overall revenue impact from a particular campaign, attribution seeks to point to a specific channel to attribute a sale.

    For example, in any given marketing campaign, you have a few marketing tactics.

    Let’s say you’re launching a limited-time product.

    You might have :

    • Paid ads via Facebook and Instagram
    • A blog post sharing how the product works
    • Organic social media posts on Instagram and TikTok
    • Email waitlist campaign building excitement around the upcoming product
    • SMS campaigns to share a limited-time discount

    So, when the time comes for the sale launch, and you generate $30,000 in revenue, what channel gets the credit ?

    Do you give credit to the paid ads on Facebook ? What about Instagram ? They got people to follow you and got them on the email waitlist.

    Do you give credit to email for reminding people of the upcoming sale ? What about your social media posts that reminded people there ?

    Or do you credit your SMS campaign that shared a limited-time discount ?

    Which channel is responsible for the sale ?

    This is what attribution is all about.

    It’s about giving credit where credit is due.

    The reason you want to attribute credit ? So you know what’s working and can double down your efforts on the high-impact marketing activities and channels.

    Leveraging incrementality and attribution together

    Incrementality and attribution aren’t competing methods of analysing what’s working.

    They’re complementary to one another and go hand in hand.

    You can (and should) use attribution and incrementality in your marketing to help understand what activities, campaigns and channels are making the biggest incremental impact on your business growth.

    Why it’s important to measure incrementality

    Incrementality is crucial to measure if you want to pour your time, money and effort into the right marketing channels and tactics.

    Here are a few reasons why you need to measure incrementality if you want to be successful with your marketing and grow your business :

    1. Accurate data

    If you want to be an effective marketer, you need to be accurate.

    You can’t blindly start marketing campaigns in hopes that you will sell many products or services.

    That’s not how it works.

    Sure, you’ll probably make some sales here and there. But to truly be effective with your work, you must measure your activities and channels correctly.

    Incrementality helps you see how each channel, tactic or campaign made a difference in your marketing.

    Matomo gives you 100% accurate data on your website activities. Unlike Google Analytics, we don’t use data sampling which limits how much data is analysed.

    Screenshot example of the Matomo dashboard

    2. Helps you to best determine the right tactics for success

    How can you plan your marketing strategy if you don’t know what’s working ?

    Think about it.

    You’ll be blindly sailing the seas without a compass telling you where to go.

    Measuring incrementality in your marketing tactics and channels helps you understand the best tactics.

    It shows you what’s moving the needle (and what’s not).

    Once you can see the most impactful tactics and channels, you can forge future campaigns that you know will work.

    3. Allows you to get the most out of your marketing budget

    Since incrementality sheds light on what’s moving your business forward, you can confidently implement your efforts on the right tactics and channels.

    Guess what happens when you start doubling down on the most impactful activities ?

    You start increasing revenue, decreasing ad spend and getting a higher return on investment.

    The result is that you will get more out of your marketing budget.

    Not only will you boost revenue, but you’ll also be able to boost profit margins since you’re not wasting money on ineffective tactics.

    4. Increase traffic

    When you see what’s truly working in your business, you can figure out what channels and tactics you should be working.

    Incrementality helps you understand not only what your best revenue tactics are but also what channels and campaigns are bringing in the most traffic.

    When you can increase traffic, you can increase your overall marketing impact.

    5. Increase revenue

    Finally, with increased traffic, the inevitable result is more conversions.

    More conversions mean more revenue.

    Incrementality gives you a vision of the tactics and channels that are converting the best.

    If you can see that your SMS campaigns are driving the best ROI, then you know that you’ll grow your revenue by pouring more into acquiring SMS leads.

    By calculating incrementality regularly, you can rest assured that you’re only investing time and money into the most impactful activities in terms of revenue generation.

    How to calculate and test incrementality in marketing

    Now that you understand how incrementality works and why it’s important to calculate, the question is : 

    How do you calculate and conduct incrementality tests ?

    Given the ever-changing marketing landscape, it’s crucial to understand how to calculate and test incrementally in your business.

    If you’re not sure how incrementality testing works, then follow these simple steps :

    How to test and analyze incrementality in marketing?

    Your first step to get an incrementality measurement is to conduct what’s referred to as a “holdout test.”

    It’s not a robust test, but it’s an easy way to get the ball rolling with incrementality.

    Here’s how it works :

    1. Choose your target audience.

    With Matomo’s segmentation feature, you can get pretty specific with your target audience, such as :

      • Visitors from the UK
      • Returning visitors
      • Mobile users
      • Visitors who clicked on a specific ad
    1. Split your audience into two groups :
      • Control group (60% of the segment)
      • Test group (40% of the segment)
    1. Target the control group with your marketing tactic (the simpler the tactic, the better).
    1. Target the test group with a different marketing tactic.
    1. Analyse the results. The difference between the control and test groups is the incremental lift in results. The new marketing tactic is either more effective or not.
    1. Repeat the test with a new control group (with an updated tactic) and a new test group (with a new tactic).

    Matomo can help you analyse the results of your campaigns in our Goals feature. Set up business objectives so you can easily track different goals like conversions.

    Try Matomo for Free

    Get the web insights you need, without compromising data accuracy.

    No credit card required

    Here’s an example of how this incrementality testing could look in real life.

    Imagine a fitness retailer wants to start showing Facebook ads in their marketing mix.

    The marketing manager decided to conduct a holdout test. If we match our example below with the steps above, this is how the holdout test might look.

    1. They choose people who’ve purchased free weights in the past as their target audience (see how that segmentation works ?).
    2. They split this segment into a control group and a test group.
    3. For this test, they direct their regular marketing campaign to the control group (60% of the segment). The campaign includes promoting a 20% off sale on organic social media posts, email marketing, and SMS.
    4. They direct their regular marketing campaign plus Facebook ads to the test group (40% of the segment).
    5. They ran the campaign for three weeks with the goal for sale conversions and noticed :
      • The control group had a 1.5% conversion rate.
      • The test group (with Facebook ads) had a 2.1% conversion rate.
      • In this scenario, they could see the group who saw the Facebook ads convert better.
      • They created the following formula to measure the incremental lift of the Facebook ads :
    Calculation: Incrementality in marketing.
      • Here’s how the calculation works out : (2.1% – 1.5%) / 1.5% = 40%

    The Facebook ads had a positive 40% incremental lift in conversions during the sale.

    Incrementality testing isn’t a one-and-done process, though.

    While this first test is a great sign for the marketing manager, it doesn’t mean they should immediately throw all their money into Facebook ads.

    They should continue conducting tests to verify the initial test.

    Use Matomo to track incrementality today

    Incrementality can give you insights into exactly what’s working in your marketing (and what’s not) so you can design proven strategies to grow your business.

    If you want more help tracking your marketing efforts, try Matomo today.

    Our web analytics and behaviour analytics platform gives you firsthand data on your website visitors you can use to craft effective marketing strategies.

    Matomo provides 100% accurate data. Unlike other major web analytics platforms, we don’t do data sampling. What you see is what’s really going on in your website. That way, you can make more informed decisions for better results.

    At Matomo, we take privacy very seriously and include several advanced privacy protections to ensure you are in full control.

    As a fully compliant web analytics solution, we’re fully compliant with some of the world’s strictest privacy regulations like GDPR. With Matomo, you get peace of mind knowing you can make data-driven decisions while also being compliant. 

    If you’re ready to launch a data-driven marketing strategy today and grow your business, get started with our 21-day free trial now. No credit card required.