Recherche avancée

Médias (91)

Autres articles (85)

  • Encoding and processing into web-friendly formats

    13 avril 2011, par

    MediaSPIP automatically converts uploaded files to internet-compatible formats.
    Video files are encoded in MP4, Ogv and WebM (supported by HTML5) and MP4 (supported by Flash).
    Audio files are encoded in MP3 and Ogg (supported by HTML5) and MP3 (supported by Flash).
    Where possible, text is analyzed in order to retrieve the data needed for search engine detection, and then exported as a series of image files.
    All uploaded files are stored online in their original format, so you can (...)

  • MediaSPIP Player : problèmes potentiels

    22 février 2011, par

    Le lecteur ne fonctionne pas sur Internet Explorer
    Sur Internet Explorer (8 et 7 au moins), le plugin utilise le lecteur Flash flowplayer pour lire vidéos et son. Si le lecteur ne semble pas fonctionner, cela peut venir de la configuration du mod_deflate d’Apache.
    Si dans la configuration de ce module Apache vous avez une ligne qui ressemble à la suivante, essayez de la supprimer ou de la commenter pour voir si le lecteur fonctionne correctement : /** * GeSHi (C) 2004 - 2007 Nigel McNie, (...)

  • Submit bugs and patches

    13 avril 2011

    Unfortunately a software is never perfect.
    If you think you have found a bug, report it using our ticket system. Please to help us to fix it by providing the following information : the browser you are using, including the exact version as precise an explanation as possible of the problem if possible, the steps taken resulting in the problem a link to the site / page in question
    If you think you have solved the bug, fill in a ticket and attach to it a corrective patch.
    You may also (...)

Sur d’autres sites (7147)

  • The Ultimate List of Alternatives to Google Products

    2 août 2022, par Erin — Privacy

    For many businesses, Google products can play an integral part in the productivity, function and even success of the company. This is because Google has designed their digital ecosystem to infiltrate every aspect of your work and personal life at low-to-no cost.

    On the surface, this seems like a no-brainer. Why not have a cost-effective and seamlessly connected tech stack ? It’s the complete package. 

    From Gmail to Google Analytics, it becomes hard to untangle yourself from this intricate web Google has managed to spin. But like a web, you know there’s also a catch.

    This leads us to the big question… Why stop ?

    In this blog, we’ll cover :

    Why de-Google ?

    Google products are convenient and seemingly free. However, in recent years, Google’s name has become synonymous with privacy breaches, data leaks and illegal under the General Data Protection Regulation (GDPR).

    As their track record shows a glaring disregard for data protection, a growing list of EU member countries like Austria, France, Denmark and Italy have banned Google products, such as Google Analytics, Google Workspace and Google Chromebook.

    Google offers free products and services, but not out of altruism. There’s a trade-off. By using Google’s “free” products, your customers’ and your own online activity becomes a commodity that can be sold to advertisers.

    When the risks of using Google products are considered, it becomes clear the need to plot a pathway to de-Google your business. If you’re wondering how in the world to uncoil from this web, fortunately, there are plenty of privacy-friendly, secure alternatives to Google products that you can choose.

    Disclaimer : Below, we’ve tried our best to provide a comprehensive list of alternatives to Google products for businesses, but because you know your business best, we’d also encourage you to do your own research to ensure the tool will suit your unique needs.

    Best Google alternative tools for business

    Overall business tools

    Google Workspace alternatives

    Google Workspace isn’t GDPR compliant by default, so businesses are at risk of fines and reputational damage. More EU countries are reaching the same conclusion that Google products are violating EU law. Data Protection Authorities from Norway and Denmark have deemed Google Workspace illegal in accordance with the GDPR. 

    Nextcloud

    Nextcloud is an open-source and self-hosted productivity platform that offers a suite of services to replace the major features found in Google Workspace, such as Google Drive, Calendar, Docs, Forms and Tasks. 

    You can share files and collaborate without worrying about data being shared with unauthorised individuals or companies. As a self-hosted suite, you’re in full control of where your data is, who has access to it and can comply with the strictest of data protection legislations.

    Nextcloud dashboard
    Zoho

    Zoho is a Google Workspace alternative built on the same principles as Google’s productivity suite. It offers a suite of online office tools, including email, calendar and task management, but with an emphasis on privacy protection. Zoho doesn’t rely on advertising revenue to support their business which means your personal data will never be sold or used for targeted ads. 

    With over 75 million users globally, Zoho offers data encryption at rest and at transit, multi-factor authentication and complies with strict security standards set by HIPAA, the Cloud Security Alliance and the GDPR.

    Zoho dashboard

    Gmail alternatives

    Google only encrypts emails via STARTTLS. In other words, your data isn’t end-to-end encrypted and can be decrypted by them at any time. Gmail also has a history of allowing third-party app developers that work with Gmail to access private and personal Gmail messages for their own market research purposes.

    ProtonMail

    ProtonMail is a secure, open-source email service that provides end-to-end encryption, so only the sender and receiver can access the messages. Proton deliberately doesn’t possess the key needed to decrypt any part of the message, so you know your sensitive business information is always private. 

    To protect users from digital surveillance, they also provide enhanced tracking protections and don’t rely on ads, so your data isn’t mined for advertising purposes. Not only that, you can also sync ProtonMail with a host of other Google alternative products, such as Proton Calendar and Proton Drive.

    Proton Mail
    Mailfence

    Mailfence is a highly secure communications and planning platform that offers a complete email suite, as well as, Documents, a Calendar and Groups. It provides end-to-end encryption and comes with a built-in data loss prevention system that prevents unauthorised access to your sensitive information. 

    Mailfence is completely ad-free and promises to never commercialise its databases or share data with third parties for targeted ads.

    Mailfence
    Tutanota

    Tutanota is an open-source email service known as one of the first to offer end-to-end encryption. It boasts a user-friendly interface and offers a fast, simple and secure email service that works on web and mobile platforms. Stringent security, in addition to TOTP and U2F for two-factor authentication means you control who has access to your email and messages. 

    It requires no phone number or personal information to register for a free account. In addition, Tutanota doesn’t earn money through ads, its servers are based in Europe and it is fully GDPR compliant.

    Google Calendar alternatives

    Calendars can contain a lot of personal information (who you are meeting, location, contact info, etc.), which is well worth keeping private. 

    Proton Calendar

    With Proton Calendar all event details – participants, locations, event names, descriptions and notes are end-to-end encrypted. It has a clean and easy-to-use interface, and you get a full set of advanced features to replace Google Calendar, such as the ability to create events and reminders, add multiple calendars and set up repeating events. You can easily sync all your calendars between mobile and desktop apps.

    Mailfence Calendar

    Mailfence Calendar lets you manage, schedule and track your events and meetings. Similar to Google Calendar, you can invite people to events using their Mailfence email IDs, but it doesn’t track your location or email address.

    Tutanota Calendar

    Tutanota Calendar offers built-in encryption, so no one else can decrypt and read your information.

    You can keep track of your appointments and meetings in a secure environment that only you have access to. You get features, such as day/week/month view, all-day events, recurring events, upcoming events view and shared calendars. You can also sync it with other apps such as Outlook.

    Tutanota calendar event
    Nextcloud Calendar app

    Nextcloud also offers a Calendar app which easily syncs events from different devices with your Nextcloud account. You can integrate it with other Nextcloud apps like Contacts, Talk and Tasks.

    Nextcloud calendar

    Google Drive alternatives

    The GDPR emphasises end-to-end encryption as a safeguard against data leaks, but Google Drive isn’t end-to-end encrypted, so Google has access to the data on its servers. 

    In their privacy policy, they also state that this data can be analysed for advertising purposes, so although you’re using “free” Cloud storage, users need to be aware that they’re paying for this by giving Google access to any and all data stored in Google Drive.

    Proton Drive

    Proton Drive is a secure and private Cloud storage service that provides you with an easy-to-use, customisable and secure file management system.

    It uses end-to-end encryption to secure your data and keep it safe from prying eyes. As you have full control over your data, you can decide how long it’s stored and who has access to it. You can also choose how much of your information is shared with other users.

    Proton Drive
    Nextcloud

    Nextcloud works on your own server, so you can access and share your data wherever you are. It’s a file hosting service that lets you store files, sync them across your devices and collaborate with others on projects. 

    It also provides encryption for all the files that you store on its servers, so you can rest assured that no one can see your information without your permission.

    Nextcloud Drive
    Syncthing

    Syncthing is a free, open-source file synchronisation program that allows you to store and access your files wherever you are. It’s designed to be fast, secure and easy to use, making it a great alternative to Google Drive. 

    With Syncthing, you can sync files across multiple computers and mobile devices at once. So if you create, delete or modify files on one machine, they will automatically be replicated on other devices. Data is saved directly to a location you choose, so you can securely backup your data without needing a third-party cloud service.

    Google Docs alternatives

    Google states they can “collect information” from Google-hosted content such as Docs by means of automated scanning. 

    Not only does this stoke spying fears, it also raises concerns over who holds power over your content. If they look through your docs and decide that you’ve violated their terms of service, you can get locked out of your Google Docs – as was the case when a National Geographic crime reporter had her story “frozen” by Google.

    LibreOffice

    LibreOffice is a free, open-source office suite with all the features you need to create and edit documents, presentations and spreadsheets. It’s compatible with many different languages and all Microsoft Office file formats. 

    Unlike Google Docs, LibreOffice doesn’t store your documents on the Cloud. As it runs on your own computer, you maintain complete control and the data is kept as private and as secure as you wish. LibreOffice also has an online version that works with most web browsers and can be used on Windows, Mac and Linux operating systems. 

    The open-source nature ensures security as the code is constantly improved and scouted for vulnerabilities.

    Nextcloud Office

    Like Google Docs, Nextcloud Office lets you create new documents and spreadsheets and collaborate with teammates or colleagues. But unlike Google Docs, Nextcloud doesn’t collect any data on who is using its platform, or what they’re doing on it. You can even encrypt the files you store in Nextcloud, so no one else can see them unless you give them access to your account.

    Nextcloud Office

    Google Keep alternative

    Standard Notes

    Standard Notes is an open-source online notebook app that offers a variety of useful features, such as tasks, to-dos and spreadsheets. 

    Unlike Google Keep, which has access to your notes, Standard Notes is end-to-end encrypted, which protects all your information and keeps it securely synced across all your devices. Standard Notes supports text, images and audio notes. As open-source software, they value transparency and trust and don’t rely on tracking or intrusive ads.

    Standard notes dashboard

    Google Chrome alternatives

    Google Chrome is notorious for stalking users and collecting information for their own gains. Their browser fuels their data gathering infrastructure by being able to collect info about your search history, location, personal data and product interaction data for “personalisation” purposes – essentially to build a profile of you to sell to advertisers.

    Firefox

    Firefox is one of the most secure browsers for privacy and is trusted by 220 million users. It easily compares with Chrome in terms of ease of use and performance. 

    On top of that it offers enhanced privacy protections, so you get a browser that doesn’t stalk you and isn’t riddled with ads.

    Firefox
  • H.264 muxed to MP4 using libavformat not playing back

    14 mai 2015, par Brad Mitchell

    I am trying to mux H.264 data into a MP4 file. There appear to be no errors in saving this H.264 Annex B data out to an MP4 file, but the file fails to playback.

    I’ve done a binary comparison on the files and the issue seems to be somewhere in what is being written to the footer (trailer) of the MP4 file.

    I suspect it has to be something with the way the stream is being created or something.

    Init :

    AVOutputFormat* fmt = av_guess_format( 0, "out.mp4", 0 );
    oc = avformat_alloc_context();
    oc->oformat = fmt;
    strcpy(oc->filename, filename);

    Part of this prototype app I have is creating a png file for each IFrame. So when the first IFrame is encountered, I create the video stream and write the av header etc :

    void addVideoStream(AVCodecContext* decoder)
    {
       videoStream = av_new_stream(oc, 0);
       if (!videoStream)
       {
            cout << "ERROR creating video stream" << endl;
            return;        
       }
       vi = videoStream->index;    
       videoContext = videoStream->codec;      
       videoContext->codec_type = AVMEDIA_TYPE_VIDEO;
       videoContext->codec_id = decoder->codec_id;
       videoContext->bit_rate = 512000;
       videoContext->width = decoder->width;
       videoContext->height = decoder->height;
       videoContext->time_base.den = 25;
       videoContext->time_base.num = 1;    
       videoContext->gop_size = decoder->gop_size;
       videoContext->pix_fmt = decoder->pix_fmt;      

       if (oc->oformat->flags & AVFMT_GLOBALHEADER)
           videoContext->flags |= CODEC_FLAG_GLOBAL_HEADER;

       av_dump_format(oc, 0, filename, 1);

       if (!(oc->oformat->flags & AVFMT_NOFILE))
       {
           if (avio_open(&oc->pb, filename, AVIO_FLAG_WRITE) < 0) {
           cout << "Error opening file" << endl;
       }
       avformat_write_header(oc, NULL);
    }

    I write packets out :

    unsigned char* data = block->getData();
    unsigned char videoFrameType = data[4];
    int dataLen = block->getDataLen();

    // store pps
    if (videoFrameType == 0x68)
    {
       if (ppsFrame != NULL)
       {
           delete ppsFrame; ppsFrameLength = 0; ppsFrame = NULL;
       }
       ppsFrameLength = block->getDataLen();
       ppsFrame = new unsigned char[ppsFrameLength];
       memcpy(ppsFrame, block->getData(), ppsFrameLength);
    }
    else if (videoFrameType == 0x67)
    {
       // sps
       if (spsFrame != NULL)
       {
           delete spsFrame; spsFrameLength = 0; spsFrame = NULL;
    }
       spsFrameLength = block->getDataLen();
       spsFrame = new unsigned char[spsFrameLength];
       memcpy(spsFrame, block->getData(), spsFrameLength);                
    }                                          

    if (videoFrameType == 0x65 || videoFrameType == 0x41)
    {
       videoFrameNumber++;
    }
    if (videoFrameType == 0x65)
    {
       decodeIFrame(videoFrameNumber, spsFrame, spsFrameLength, ppsFrame, ppsFrameLength, data, dataLen);
    }

    if (videoStream != NULL)
    {
       AVPacket pkt = { 0 };
       av_init_packet(&pkt);
       pkt.stream_index = vi;
       pkt.flags = 0;                      
       pkt.pts = pkt.dts = 0;                                  

       if (videoFrameType == 0x65)
       {
           // combine the SPS PPS & I frames together
           pkt.flags |= AV_PKT_FLAG_KEY;                                                  
           unsigned char* videoFrame = new unsigned char[spsFrameLength+ppsFrameLength+dataLen];
           memcpy(videoFrame, spsFrame, spsFrameLength);
           memcpy(&videoFrame[spsFrameLength], ppsFrame, ppsFrameLength);
           memcpy(&videoFrame[spsFrameLength+ppsFrameLength], data, dataLen);

           // overwrite the start code (00 00 00 01 with a 32-bit length)
           setLength(videoFrame, spsFrameLength-4);
           setLength(&videoFrame[spsFrameLength], ppsFrameLength-4);
           setLength(&videoFrame[spsFrameLength+ppsFrameLength], dataLen-4);
           pkt.size = dataLen + spsFrameLength + ppsFrameLength;
           pkt.data = videoFrame;
           av_interleaved_write_frame(oc, &pkt);
           delete videoFrame; videoFrame = NULL;
       }
       else if (videoFrameType != 0x67 && videoFrameType != 0x68)
       {  
           // Send other frames except pps & sps which are caught and stored                  
           pkt.size = dataLen;
           pkt.data = data;
           setLength(data, dataLen-4);                    
           av_interleaved_write_frame(oc, &pkt);
       }

    Finally to close the file off :

    av_write_trailer(oc);
    int i = 0;
    for (i = 0; i < oc->nb_streams; i++)
    {
       av_freep(&oc->streams[i]->codec);
       av_freep(&oc->streams[i]);      
    }

    if (!(oc->oformat->flags & AVFMT_NOFILE))
    {
       avio_close(oc->pb);
    }
    av_free(oc);

    If I take the H.264 data alone and convert it :

    ffmpeg -i recording.h264 -vcodec copy recording.mp4

    All but the "footer" of the files are the same.

    Output from my program :
    readrec recording.tcp out.mp4
    ** START * 01-03-2013 14:26:01 180000
    Output #0, mp4, to ’out.mp4’ :
    Stream #0:0 : Video : h264, yuv420p, 352x288, q=2-31, 512 kb/s, 90k tbn, 25 tbc
    * END ** 01-03-2013 14:27:01 102000
    Wrote 1499 video frames.

    If I try to convert using ffmpeg the MP4 file created using CODE :

    ffmpeg -i out.mp4 -vcodec copy out2.mp4
    ffmpeg version 0.11.1 Copyright (c) 2000-2012 the FFmpeg developers
         built on Mar  7 2013 12:49:22 with suncc 0x5110
         configuration: --extra-cflags=-KPIC -g --disable-mmx
         --disable-protocol=udp --disable-encoder=nellymoser --cc=cc --cxx=CC
    libavutil      51. 54.100 / 51. 54.100
    libavcodec     54. 23.100 / 54. 23.100
    libavformat    54.  6.100 / 54.  6.100
    libavdevice    54.  0.100 / 54.  0.100
    libavfilter     2. 77.100 /  2. 77.100
    libswscale      2.  1.100 /  2.  1.100
    libswresample   0. 15.100 /  0. 15.100
    h264 @ 12eaac0] no frame!
       Last message repeated 1 times
    [h264 @ 12eaac0] slice type too large (0) at 0 0
    [h264 @ 12eaac0] decode_slice_header error
    [h264 @ 12eaac0] no frame!
       Last message repeated 23 times
    [h264 @ 12eaac0] slice type too large (0) at 0 0
    [h264 @ 12eaac0] decode_slice_header error
    [h264 @ 12eaac0] no frame!
       Last message repeated 74 times
    [h264 @ 12eaac0] slice type too large (0) at 0 0
    [h264 @ 12eaac0] decode_slice_header error
    [h264 @ 12eaac0] no frame!
       Last message repeated 64 times
    [h264 @ 12eaac0] slice type too large (0) at 0 0
    [h264 @ 12eaac0] decode_slice_header error
    [h264 @ 12eaac0] no frame!
       Last message repeated 34 times
    [h264 @ 12eaac0] slice type too large (0) at 0 0
    [h264 @ 12eaac0] decode_slice_header error
    [h264 @ 12eaac0] no frame!
       Last message repeated 49 times
    [h264 @ 12eaac0] slice type too large (0) at 0 0
    [h264 @ 12eaac0] decode_slice_header error
    [h264 @ 12eaac0] no frame!
       Last message repeated 24 times
    [h264 @ 12eaac0] Partitioned H.264 support is incomplete
    [h264 @ 12eaac0] no frame!
       Last message repeated 23 times
    [h264 @ 12eaac0] sps_id out of range
    [h264 @ 12eaac0] no frame!
       Last message repeated 148 times
    [h264 @ 12eaac0] sps_id (32) out of range
       Last message repeated 1 times
    [h264 @ 12eaac0] no frame!
       Last message repeated 33 times
    [h264 @ 12eaac0] slice type too large (0) at 0 0
    [h264 @ 12eaac0] decode_slice_header error
    [h264 @ 12eaac0] no frame!
       Last message repeated 128 times
    [h264 @ 12eaac0] sps_id (32) out of range
       Last message repeated 1 times
    [h264 @ 12eaac0] no frame!
       Last message repeated 3 times
    [h264 @ 12eaac0] slice type too large (0) at 0 0
    [h264 @ 12eaac0] decode_slice_header error
    [h264 @ 12eaac0] no frame!
       Last message repeated 3 times
    [h264 @ 12eaac0] slice type too large (0) at 0 0
    [h264 @ 12eaac0] decode_slice_header error
    [h264 @ 12eaac0] no frame!
       Last message repeated 309 times
    [h264 @ 12eaac0] sps_id (32) out of range
       Last message repeated 1 times
    [h264 @ 12eaac0] no frame!
       Last message repeated 192 times
    [h264 @ 12eaac0] Partitioned H.264 support is incomplete
    [h264 @ 12eaac0] no frame!
       Last message repeated 73 times
    [h264 @ 12eaac0] sps_id (32) out of range
       Last message repeated 1 times
    [h264 @ 12eaac0] no frame!
       Last message repeated 99 times
    [h264 @ 12eaac0] sps_id (32) out of range
       Last message repeated 1 times
    [h264 @ 12eaac0] no frame!
       Last message repeated 197 times
    [mov,mp4,m4a,3gp,3g2,mj2 @ 12e3100] decoding for stream 0 failed
    [mov,mp4,m4a,3gp,3g2,mj2 @ 12e3100] Could not find codec parameters
    (Video: h264 (avc1 / 0x31637661), 393539 kb/s)
    out.mp4: could not find codec parameters

    I really do not know where the issue is, except it has to be something to do with the way the streams are being set up. I’ve looked at bits of code from where other people are doing a similar thing, and tried to use this advice in setting up the streams, but to no avail !


    The final code which gave me a H.264/AAC muxed (synced) file is as follows. First a bit of background information. The data is coming from an IP camera. The data is presented via a 3rd party API as video/audio packets. The video packets are presented as the RTP payload data (no header) and consist of NALU’s that are reconstructed and converted to H.264 video in Annex B format. AAC audio is presented as raw AAC and is converted to adts format to enable playback. These packets have been put into a bitstream format that allows the transmission of the timestamp (64 bit milliseconds since Jan 1 1970) along with a few other things.

    This is more or less a prototype and is not clean in any respects. It probably leaks bad. I do however, hope this helps anyone else out trying to achieve something similar to what I am.

    Globals :

    AVFormatContext* oc = NULL;
    AVCodecContext* videoContext = NULL;
    AVStream* videoStream = NULL;
    AVCodecContext* audioContext = NULL;
    AVStream* audioStream = NULL;
    AVCodec* videoCodec = NULL;
    AVCodec* audioCodec = NULL;
    int vi = 0;  // Video stream
    int ai = 1;  // Audio stream

    uint64_t firstVideoTimeStamp = 0;
    uint64_t firstAudioTimeStamp = 0;
    int audioStartOffset = 0;

    char* filename = NULL;

    Boolean first = TRUE;

    int videoFrameNumber = 0;
    int audioFrameNumber = 0;

    Main :

    int main(int argc, char* argv[])
    {
       if (argc != 3)
       {  
           cout &lt;&lt; argv[0] &lt;&lt; " <stream playback="playback" file="file"> <output mp4="mp4" file="file">" &lt;&lt; endl;
           return 0;
       }
       char* input_stream_file = argv[1];
       filename = argv[2];

       av_register_all();    

       fstream inFile;
       inFile.open(input_stream_file, ios::in);

       // Used to store the latest pps &amp; sps frames
       unsigned char* ppsFrame = NULL;
       int ppsFrameLength = 0;
       unsigned char* spsFrame = NULL;
       int spsFrameLength = 0;

       // Setup MP4 output file
       AVOutputFormat* fmt = av_guess_format( 0, filename, 0 );
       oc = avformat_alloc_context();
       oc->oformat = fmt;
       strcpy(oc->filename, filename);

       // Setup the bitstream filter for AAC in adts format.  Could probably also achieve
       // this by stripping the first 7 bytes!
       AVBitStreamFilterContext* bsfc = av_bitstream_filter_init("aac_adtstoasc");
       if (!bsfc)
       {      
           cout &lt;&lt; "Error creating adtstoasc filter" &lt;&lt; endl;
           return -1;
       }

       while (inFile.good())
       {
           TcpAVDataBlock* block = new TcpAVDataBlock();
           block->readStruct(inFile);
           DateTime dt = block->getTimestampAsDateTime();
           switch (block->getPacketType())
           {
               case TCP_PACKET_H264:
               {      
                   if (firstVideoTimeStamp == 0)
                       firstVideoTimeStamp = block->getTimeStamp();
                   unsigned char* data = block->getData();
                   unsigned char videoFrameType = data[4];
                   int dataLen = block->getDataLen();

                   // pps
                   if (videoFrameType == 0x68)
                   {
                       if (ppsFrame != NULL)
                       {
                           delete ppsFrame; ppsFrameLength = 0;
                           ppsFrame = NULL;
                       }
                       ppsFrameLength = block->getDataLen();
                       ppsFrame = new unsigned char[ppsFrameLength];
                       memcpy(ppsFrame, block->getData(), ppsFrameLength);
                   }
                   else if (videoFrameType == 0x67)
                   {
                       // sps
                       if (spsFrame != NULL)
                       {
                           delete spsFrame; spsFrameLength = 0;
                           spsFrame = NULL;
                       }
                       spsFrameLength = block->getDataLen();
                       spsFrame = new unsigned char[spsFrameLength];
                       memcpy(spsFrame, block->getData(), spsFrameLength);                  
                   }                                          

                   if (videoFrameType == 0x65 || videoFrameType == 0x41)
                   {
                       videoFrameNumber++;
                   }
                   // Extract a thumbnail for each I-Frame
                   if (videoFrameType == 0x65)
                   {
                       decodeIFrame(h264, spsFrame, spsFrameLength, ppsFrame, ppsFrameLength, data, dataLen);
                   }
                   if (videoStream != NULL)
                   {
                       AVPacket pkt = { 0 };
                       av_init_packet(&amp;pkt);
                       pkt.stream_index = vi;
                       pkt.flags = 0;          
                       pkt.pts = videoFrameNumber;
                       pkt.dts = videoFrameNumber;          
                       if (videoFrameType == 0x65)
                       {
                           pkt.flags = 1;                          

                           unsigned char* videoFrame = new unsigned char[spsFrameLength+ppsFrameLength+dataLen];
                           memcpy(videoFrame, spsFrame, spsFrameLength);
                           memcpy(&amp;videoFrame[spsFrameLength], ppsFrame, ppsFrameLength);

                           memcpy(&amp;videoFrame[spsFrameLength+ppsFrameLength], data, dataLen);
                           pkt.data = videoFrame;
                           av_interleaved_write_frame(oc, &amp;pkt);
                           delete videoFrame; videoFrame = NULL;
                       }
                       else if (videoFrameType != 0x67 &amp;&amp; videoFrameType != 0x68)
                       {                      
                           pkt.size = dataLen;
                           pkt.data = data;
                           av_interleaved_write_frame(oc, &amp;pkt);
                       }                      
                   }
                   break;
               }

           case TCP_PACKET_AAC:

               if (firstAudioTimeStamp == 0)
               {
                   firstAudioTimeStamp = block->getTimeStamp();
                   uint64_t millseconds_difference = firstAudioTimeStamp - firstVideoTimeStamp;
                   audioStartOffset = millseconds_difference * 16000 / 1000;
                   cout &lt;&lt; "audio offset: " &lt;&lt; audioStartOffset &lt;&lt; endl;
               }

               if (audioStream != NULL)
               {
                   AVPacket pkt = { 0 };
                   av_init_packet(&amp;pkt);
                   pkt.stream_index = ai;
                   pkt.flags = 1;          
                   pkt.pts = audioFrameNumber*1024;
                   pkt.dts = audioFrameNumber*1024;
                   pkt.data = block->getData();
                   pkt.size = block->getDataLen();
                   pkt.duration = 1024;

                   AVPacket newpacket = pkt;                      
                   int rc = av_bitstream_filter_filter(bsfc, audioContext,
                       NULL,
                       &amp;newpacket.data, &amp;newpacket.size,
                       pkt.data, pkt.size,
                       pkt.flags &amp; AV_PKT_FLAG_KEY);

                   if (rc >= 0)
                   {
                       //cout &lt;&lt; "Write audio frame" &lt;&lt; endl;
                       newpacket.pts = audioFrameNumber*1024;
                       newpacket.dts = audioFrameNumber*1024;
                       audioFrameNumber++;
                       newpacket.duration = 1024;                  

                       av_interleaved_write_frame(oc, &amp;newpacket);
                       av_free_packet(&amp;newpacket);
                   }  
                   else
                   {
                       cout &lt;&lt; "Error filtering aac packet" &lt;&lt; endl;

                   }
               }
               break;

           case TCP_PACKET_START:
               break;

           case TCP_PACKET_END:
               break;
           }
           delete block;
       }
       inFile.close();

       av_write_trailer(oc);
       int i = 0;
       for (i = 0; i &lt; oc->nb_streams; i++)
       {
           av_freep(&amp;oc->streams[i]->codec);
           av_freep(&amp;oc->streams[i]);      
       }

       if (!(oc->oformat->flags &amp; AVFMT_NOFILE))
       {
           avio_close(oc->pb);
       }

       av_free(oc);

       delete spsFrame; spsFrame = NULL;
       delete ppsFrame; ppsFrame = NULL;

       cout &lt;&lt; "Wrote " &lt;&lt; videoFrameNumber &lt;&lt; " video frames." &lt;&lt; endl;

       return 0;
    }
    </output></stream>

    The stream stream/codecs are added and the header is created in a function called addVideoAndAudioStream(). This function is called from decodeIFrame() so there are a few assumptions (which aren’t necessarily good)
    1. A video packet comes first
    2. AAC is present

    The decodeIFrame was kind of a separate prototype by where I was creating a thumbnail for each I Frame. The code to generate thumbnails was from : https://gnunet.org/svn/Extractor/src/plugins/thumbnailffmpeg_extractor.c

    The decodeIFrame function passes an AVCodecContext into addVideoAudioStream :

    void addVideoAndAudioStream(AVCodecContext* decoder = NULL)
    {
       videoStream = av_new_stream(oc, 0);
       if (!videoStream)
       {
           cout &lt;&lt; "ERROR creating video stream" &lt;&lt; endl;
           return;      
       }
       vi = videoStream->index;  
       videoContext = videoStream->codec;      
       videoContext->codec_type = AVMEDIA_TYPE_VIDEO;
       videoContext->codec_id = decoder->codec_id;
       videoContext->bit_rate = 512000;
       videoContext->width = decoder->width;
       videoContext->height = decoder->height;
       videoContext->time_base.den = 25;
       videoContext->time_base.num = 1;
       videoContext->gop_size = decoder->gop_size;
       videoContext->pix_fmt = decoder->pix_fmt;      

       audioStream = av_new_stream(oc, 1);
       if (!audioStream)
       {
           cout &lt;&lt; "ERROR creating audio stream" &lt;&lt; endl;
           return;
       }
       ai = audioStream->index;
       audioContext = audioStream->codec;
       audioContext->codec_type = AVMEDIA_TYPE_AUDIO;
       audioContext->codec_id = CODEC_ID_AAC;
       audioContext->bit_rate = 64000;
       audioContext->sample_rate = 16000;
       audioContext->channels = 1;

       if (oc->oformat->flags &amp; AVFMT_GLOBALHEADER)
       {
           videoContext->flags |= CODEC_FLAG_GLOBAL_HEADER;
           audioContext->flags |= CODEC_FLAG_GLOBAL_HEADER;
       }

       av_dump_format(oc, 0, filename, 1);

       if (!(oc->oformat->flags &amp; AVFMT_NOFILE))
       {
           if (avio_open(&amp;oc->pb, filename, AVIO_FLAG_WRITE) &lt; 0) {
               cout &lt;&lt; "Error opening file" &lt;&lt; endl;
           }
       }

       avformat_write_header(oc, NULL);
    }

    As far as I can tell, a number of assumptions didn’t seem to matter, for example :
    1. Bit Rate. The actual video bit rate was 262k whereas I specified 512kbit
    2. AAC channels. I specified mono, although the actual output was Stereo from memory

    You would still need to know what the frame rate (time base) is for the video & audio.

    Contrary to a lot of other examples, when setting pts & dts on the video packets, it was not playable. I needed to know the time base (25fps) and then set the pts & dts according to that time base, i.e. first frame = 0 (PPS, SPS, I), second frame = 1 (intermediate frame, whatever its called ;)).

    AAC I also had to make the assumption that it was 16000 hz. 1024 samples per AAC packet (You can also have AAC @ 960 samples I think) to determine the audio "offset". I added this to the pts & dts. So the pts/dts are the sample number that it is to played back at. You also need to make sure that the duration of 1024 is set in the packet before writing also.

    I have found additionally today that Annex B isn’t really compatible with any other player so AVCC format should really be used.

    These URLS helped :
    Problem to Decode H264 video over RTP with ffmpeg (libavcodec)
    http://aviadr1.blogspot.com.au/2010/05/h264-extradata-partially-explained-for.html

    When constructing the video stream, I filled out the extradata & extradata_size :

    // Extradata contains PPS &amp; SPS for AVCC format
    int extradata_len = 8 + spsFrameLen-4 + 1 + 2 + ppsFrameLen-4;
    videoContext->extradata = (uint8_t*)av_mallocz(extradata_len);
    videoContext->extradata_size = extradata_len;
    videoContext->extradata[0] = 0x01;
    videoContext->extradata[1] = spsFrame[4+1];
    videoContext->extradata[2] = spsFrame[4+2];
    videoContext->extradata[3] = spsFrame[4+3];
    videoContext->extradata[4] = 0xFC | 3;
    videoContext->extradata[5] = 0xE0 | 1;
    int tmp = spsFrameLen - 4;
    videoContext->extradata[6] = (tmp >> 8) &amp; 0x00ff;
    videoContext->extradata[7] = tmp &amp; 0x00ff;
    int i = 0;
    for (i=0;iextradata[8+i] = spsFrame[4+i];
    videoContext->extradata[8+tmp] = 0x01;
    int tmp2 = ppsFrameLen-4;  
    videoContext->extradata[8+tmp+1] = (tmp2 >> 8) &amp; 0x00ff;
    videoContext->extradata[8+tmp+2] = tmp2 &amp; 0x00ff;
    for (i=0;iextradata[8+tmp+3+i] = ppsFrame[4+i];

    When writing out the frames, don’t prepend the SPS & PPS frames, just write out the I Frame & P frames. In addition, replace the Annex B start code contained in the first 4 bytes (0x00 0x00 0x00 0x01) with the size of the I/P frame.

  • 10 Matomo Features You Possibly Didn’t Know About

    28 octobre 2022, par Erin

    Most users know Matomo as the privacy-focussed web analytics tool with data accuracy, superior to Google Analytics. 

    And we’re thrilled to be that — and more ! 

    At Matomo, our underlying product vision is to provide a full stack of accurate, user-friendly and privacy-mindful online marketing tools. 

    Over the years, we’ve expanded beyond baseline website statistics. Matomo Cloud users also get to benefit from additional powerful tools for audience segmentation, conversion optimisation, advanced event tracking and more. 

    Here are the top 10 advanced Matomo features you wish you knew about earlier (but won’t stop using now !). 

    Funnels

    At first glance, most customer journeys look sporadic. But every marketer will tell you that there is a method to almost every users’ madness. Or more precisely — there’s a method you can use to guide users towards conversions. 

    That’s called a customer journey — a schematic set of steps and actions people complete from developing awareness and interest in your solution to consideration and finally conversion.

    On average, 8 touchpoints are required to turn a prospect into a customer. Though the number can be significantly bigger in B2B sales and smaller for B2C Ecommerce websites. 

    With the Funnels feature, you can first map all the on-site touchpoints (desired actions) for different types of customers. Then examine the results you’re getting as prospects move through these checkbox steps.

    Funnel reports provide :

    • High-level metrics such as “Funnel conversion rate”, “Number of funnel conversions”, “Number of funnel entries”. 
    • Drilled-down reports for each funnel and each tracked action within it. This way you can track the success rates of each step and estimate their contribution to the cumulative effect.

    Segmented funnel reports for specific user cohorts (with Matomo Segmentation enabled).

    Funnels Report Matomo

    What makes funnels so fun (pun intended) ? The variety of use cases and configurations ! 

    You can build funnels to track conversion rates for :

    • Newsletter subscriptions
    • Job board applications 
    • Checkout or payment 
    • Product landing pages
    • Seasonal promo campaigns

    …. And pretty much any other page where users must complete a meaningful action. So go test this out. 

    Form Analytics

    On-site forms are a 101 tactic for lead generation. For most service businesses, a “contact request” or a “booking inquiry” submission means a new lead in your pipeline. 

    That said : the average on-site form conversion rates across industries stand at below 50% : 

    • Property – 37% 
    • Telecoms – 40%
    • Software — 46.83%

    That’s not bad, but it could be better. If only you could figure out why people abandon your forms….

    Oh wait, Matomo Form Analytics can supply you with answers. Form Analytics provide real-time information on key form metrics — total views, starter rate, submitter rate, conversions and more.

    Separately the average form hesitation time is also provided (in other words, the time a user contemplates if filling in a form is worth the effort). Plus, Matomo also tracks the time spent on form submission.

    You can review : 

    • Top drop-off fields – to understand where you are losing prospects. These fields should either be removed or simplified (e.g., with a dropdown menu) to increase conversions.
    • Most corrected-field – this will provide a clear indication of where your prospects are struggling with a form. Providing help text can simplify the process and increase conversions. 
    • Unesserary fields – with this metric, you’ll know which optional fields your leads aren’t interested in filling in and can remove them to help drive conversions. 

    With Form Analytics, you’ll be able to boost conversions and create a better on-site experience with accurate user data. 

    A/B testing

    Marketing is both an art and a science. A/B testing (or split testing) helps you statistically verify which creative ideas perform better. 

    A good conversion rate optimisation (CRO) practice is to test different elements and to do so often to find your top contenders.

    What can you split test ? Loads of things :

    • Page slogans and call-to-actions 
    • Button or submission form placements
    • Different landing page designs and layouts
    • Seasonal promo offers and banners
    • Pricing information 
    • Customer testimonial placements 

    More times than not, those small changes in page design or copy can lead to a double-digit lift in conversion rates. Accounting software Sage saw a 30% traffic boost after changing the homepage layout, copy and CTAs based on split test data. Depositphotos, in turn, got a 9.32% increase in account registration rate (CR) after testing a timed pop-up registration form. 

    The wrinkle ? A/B testing software isn’t exactly affordable, with tools averaging $119 – $1,995 per month. Plus, you then have to integrate a third-party tool with your website analytics for proper attribution — and this can get messy.

    Matomo saves you the hassle in both cases. An A/B testing tool is part of your Cloud subscription and plays nicely with other features — goal tracking, heatmaps, historic visitor profiles and more. 

    You can run split tests with Matomo on your websites or mobile apps — and find out if version A, B, C or D is the top performer. 

    Conversions Report Matomo

    Advertising Conversion Exports

    A well-executed search marketing or banner remarketing campaign can drive heaps of traffic to your website. But the big question is : How much of it will convert ?

    The AdTech industry has a major problem with proper attribution and, because of it, with ad fraud. 

    Globally, digital ad fraud will cost advertisers a hefty $8 billion by the end of 2022. That’s when another $74 million in ad budgets get wasted per quarter. 

    The reasons for ad budget waste may vary, but they often have a common denominator : lack of reliable conversion tracking data.

    Matomo helps you get a better sense of how you spend your cents with Advertising Conversion Reports. Unlike other MarTech analytics tools, you don’t need to embed any third-party advertising network trackers into your website or compromise user privacy.

    Instead, you can easily export accurate conversion data from Matomo (either manually via a CSV file or automated with an HTTPS link) into your Google Ads, Microsoft Advertising or Yandex Ads for cross-validation. This way you can get an objective view of the performance of different campaigns and optimise your budget allocations accordingly. 

    Find out more about tracking ad campaigns with Matomo.

    Matomo Tag Manager

    The marketing technology landscape is close to crossing 10,000 different solutions. Cross-platform advertising trackers and all sorts of customer data management tools comprise the bulk of that growing stack. 

    Remember : Each new tool embed adds extra “weight” to your web page. More tracking scripts equal slower page loading speed — and more frustration for your users. Likewise, extra embeds often means dialling up the developer (which takes time). Or tinkering with the site code yourself (which can result in errors and still raise the need to call a developer). 

    With Tag Manager, you can easily generate tags for :

    • Custom analytics reports 
    • Newsletter signups
    • Affiliates 
    • Form submission tracking 
    • Exit popups and surveys
    • Ads and more

    With Matomo Tag Manager, you can monitor, update or delete everything from one convenient interface. Finally, you can programme custom triggers — conditions when the tag gets activated — and specify data points (variables) it should collect. The latter is a great choice for staying privacy-focused and excluding any sensitive user information from processing. 

    With our tag management system (TMS), no rogue tags will mess up your analytics or conversion tracking. 

    Session recordings

    User experience (UX) plays a pivotal role in your conversion rates. 

    A five-year McKinsey study of 300 publicly listed companies found that companies with strong design practices have 32 percentage points higher revenue growth than their peers. 

    But what makes up a great website design and browsing experience ? Veteran UX designers name seven qualities :

    Source : Semantic Studios

    To figure out if your website meets all these criteria, you can use Session Recording — a tool for recording how users interact with your website. 

    By observing clicks, mouse moves, scrolls and form interactions you can determine problematic website design areas such as poor header navigation, subpar button placements or “boring” blocks of text. 

    Such observational studies are a huge part of the UX research process because they provide unbiased data on interaction. Or as Nielsen Norman Group puts it :

    “The way to get user data boils down to the basic rules of usability :

    • Watch what people actually do.
    • Do not believe what people say they do.
    • Definitely don’t believe what people predict they may do in the future.” 

    Most user behaviour analytics tools sell such functionality for a fee. With Matomo Cloud, this feature is included in your subscription. 

    Heatmaps

    While Session Replays provide qualitative insights, Heatmaps supply you with first-hand qualitative insights. Instead of individual user browsing sessions, you get consolidated data on where they click and how they scroll through your website. 

    Heatmaps Matomo

    Heatmaps are another favourite among UX designers and their CRO peers because you can :

    • Validate earlier design decisions around information architecture, page layout, button placements and so on. 
    • Develop new design hypotheses based on stats and then translate them into website design improvements. 
    • Identify distractive no-click elements that confuse users and remove them to improve conversions. 
    • Locate problematic user interface (UI) areas on specific devices or operating systems and improve them for a seamless experience.

    To get even more granular results, you can apply up to 100 Matomo segments to drill down on specific user groups, geographies or devices. 

    This way you can make data-based decisions for A/B testing, updating or redesigning your website pages. 

    Custom Alerts

    When it comes to your website, you don’t want to miss anything big — be it your biggest sales day or a sudden nosedive in traffic. 

    That’s when Custom Alerts come in handy. 

    Matomo Custom Alerts

    With a few clicks, you can set up email or text-based alerts about important website metrics. Once you hit that metric, Matomo will send a ping. 

    You can also set different types of Custom Alerts for your teams. For example, your website administrator can get alerted about critical technical performance issues such as a sudden spike in traffic. It can indicate a DDoS attack (in the worst case) — and timely resolution is crucial here. Or suggest that your website is going viral and you might need to provision extra computing resources to ensure optimal site performance.

    Your sales team, in turn, can get alerted about new form submissions, so that they can quickly move on to lead scoring and subsequent follow-ups. 

    Use cases are plentiful with this feature. 

    Custom Dashboards and Reports

    Did you know you can get a personalised view of the main Matomo dashboards ? 

    By design, we made different website stats available as separate widgets. Hence, you can cherry-pick which stats get a prominent spot. Moreover, you can create and embed custom widgets into your Matomo dashboard to display third-party insights (e.g., POS data).

    Set up custom dashboard views for different teams, business stakeholders or clients to keep them in the loop on relevant website metrics. 

    Custom Reports feature, in turn, lets you slice and dice your traffic analytics the way you please. You can combine up to three different data dimensions per report and then add any number of supported metrics to get a personalised analytics report.

    For example, to zoom in on your website performance in a specific target market you can apply “location” (e.g., Germany) and “action type” (e.g., app downloads) dimensions and then get segmented data on metrics such as total visits, conversion rates, revenue and more. 

    Get to know even more ways to customise Matomo deployment.

    Roll Up Report

    Need to get aggregated traffic analytics from multiple web properties, but not ready to pay $150K per year for Google Analytics 360 for that ?

    We’ve got you with Roll-Up Reporting. You can get a 360-degree view into important KPIs like global revenue, conversion rates or form performance across multiple websites, online stores, mobile apps and even Intranet properties.

    Roll-Up-Reporting in Matomo

    Setting up this feature takes minutes, but saves you hours on manually exporting and cross-mapping data from different web analytics tools. 

    Channel all those saved hours into more productive things like increasing your conversion rates or boosting user engagement

    Avoid Marketing Tool Sprawl with Matomo 

    With Matomo as your website analytics and conversion optimisation app, you don’t need to switch between different systems, interfaces or have multiple tracking codes embedded on your site.

    And you don’t need to cultivate a disparate (and expensive !) MarTech tool stack — and then figure out if each of your tools is compliant with global privacy laws.

    All the tools you need are conveniently housed under one roof. 

    Want to learn more about Matomo features ? Check out product training videos next !