Recherche avancée

Médias (1)

Mot : - Tags -/stallman

Autres articles (97)

  • MediaSPIP 0.1 Beta version

    25 avril 2011, par

    MediaSPIP 0.1 beta is the first version of MediaSPIP proclaimed as "usable".
    The zip file provided here only contains the sources of MediaSPIP in its standalone version.
    To get a working installation, you must manually install all-software dependencies on the server.
    If you want to use this archive for an installation in "farm mode", you will also need to proceed to other manual (...)

  • 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 (...)

  • 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 (...)

Sur d’autres sites (12064)

  • node.js ffmpeg pass directly to aws s3 bucket

    30 décembre 2022, par Eivydas Vickus

    How to pass ffmpeg output directly to aws s3 bucket ? It should not store output file on my pc. This is my code.

    


    &#xA;    import {&#xA;      DeleteObjectCommand,&#xA;      GetObjectCommand,&#xA;      PutObjectCommand,&#xA;      PutObjectCommandInput,&#xA;      S3,&#xA;      S3Client,&#xA;    } from &#x27;@aws-sdk/client-s3&#x27;;&#xA;    import { Inject, Injectable } from &#x27;@nestjs/common&#x27;;&#xA;    import { ConfigType } from &#x27;@nestjs/config&#x27;;&#xA;    import { nanoid } from &#x27;nanoid&#x27;;&#xA;    import awsConfig from &#x27;./aws.config&#x27;;&#xA;    import * as path from &#x27;path&#x27;;&#xA;    import { VideoInterface } from &#x27;../video/video.interface&#x27;;&#xA;    import { PassThrough } from &#x27;node:stream&#x27;;&#xA;&#xA;    @Injectable()&#xA;    export class S3BucketService {&#xA;      public readonly client = new S3Client({&#xA;        region: this.config.AWS_BUCKET_REGION,&#xA;        credentials: {&#xA;          accessKeyId: this.config.AWS_ACCESS_KEY,&#xA;          secretAccessKey: this.config.AWS_SECRET_KEY,&#xA;        },&#xA;      });&#xA;      constructor(&#xA;        @Inject(awsConfig.KEY)&#xA;        private readonly config: ConfigType<typeof awsconfig="awsconfig">,&#xA;      ) {}&#xA;&#xA;      async videoPut(putObjectInput: Omit) {&#xA;        return new PutObjectCommand({&#xA;          ...putObjectInput,&#xA;          Bucket: this.config.AWS_BUCKET_NAME,&#xA;        });&#xA;      }&#xA;&#xA;      async uploadFile({ fileName, file, folder }: VideoInterface) {&#xA;        const fullPath = path.normalize(`${folder}/${fileName}`);&#xA;        return await this.client.send(&#xA;          await this.videoPut({&#xA;            Key: fullPath,&#xA;            Body: file,&#xA;          }),&#xA;        );&#xA;      }&#xA;     }&#xA;</typeof>

    &#xA;

    &#xA;        const passthroughs = new PassThrough();&#xA;        await new Promise<void>(async (resolve, reject) => {&#xA;          ffmpeg(fs.createReadStream(file.path))&#xA;            .format(&#x27;webm&#x27;)&#xA;            .outputOptions([&#xA;              `-vf scale=${videoOptions[2].scale}`,&#xA;              `-b:v ${videoOptions[2].avgBitRate}`,&#xA;              `-minrate ${videoOptions[2].minBitRate}`,&#xA;              `-maxrate ${videoOptions[2].maxBitRate}`,&#xA;              `-tile-columns ${videoOptions[2].tileColumns}`,&#xA;              `-g ${videoOptions[2].g}`,&#xA;              `-threads ${videoOptions[2].threads}`,&#xA;              `-quality ${videoOptions[2].quality}`,&#xA;              `-crf ${videoOptions[2].crf}`,&#xA;              `-c:v ${videoOptions[2].videoCodec}`,&#xA;              `-c:a ${videoOptions[2].audioCodec}`,&#xA;              `-speed ${videoOptions[2].speed}`,&#xA;              `-y`,&#xA;            ])&#xA;            .pipe(passthroughs, { end: true })&#xA;            .on(&#x27;error&#x27;, (err) => {&#xA;              reject(err);&#xA;              throw new InternalServerErrorException(err);&#xA;            })&#xA;            .on(&#x27;data&#x27;, (data) => {&#xA;              console.log({ data });&#xA;            })&#xA;            .on(&#x27;end&#x27;, async () => {&#xA;              console.log(&#x27;Video conversion complete&#x27;);&#xA;              resolve();&#xA;            });&#xA;        });&#xA;&#xA;        await this.s3BucketService.uploadFile({&#xA;          folder: AwsFolder.VIDEOS,&#xA;          file: passthroughs,&#xA;          fileName: `${nanoid()}_${videoOptions[2].scale}.webm`,&#xA;        });&#xA;&#xA;</void>

    &#xA;

    However i am getting error Error: Output stream closed. I saw on google different variants with Passthrough none of them are working. So how it should be done ? By The Way I am using @aws-sdk/client-s3 and most solutions on google is using aws sdk-2. Maybe streams work different with version 3 ?

    &#xA;

  • When I use ffmpeg to go from a video to frames, and then back to video, the duration is different between the videos

    24 février 2024, par bluepanda

    I am trying to use ffmpeg to convert from a .mp4 (or .mov) video into individual frames, do some processing on those frames, and then convert back to .mp4. The problem is that the resulting video I create is a different duration than the input - I can see this visually when I play the two videos side by side. The difference is not large (i.e. 00:00:00.50 for the input video and 00:00:00.52 for the output video), but when the videos are looped next to each other they get out of sync.

    &#xA;

    Here is information about the input video retrieved using fluent-ffmpeg's ffmpeg.ffprobe(videoPath) :

    &#xA;

    metadata {&#xA;  streams: [&#xA;    {&#xA;      index: 0,&#xA;      codec_name: &#x27;h264&#x27;,&#xA;      codec_long_name: &#x27;H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10&#x27;,&#xA;      profile: &#x27;High&#x27;,&#xA;      codec_type: &#x27;video&#x27;,&#xA;      codec_tag_string: &#x27;avc1&#x27;,&#xA;      codec_tag: &#x27;0x31637661&#x27;,&#xA;      width: 1080,&#xA;      height: 1920,&#xA;      coded_width: 1080,&#xA;      coded_height: 1920,&#xA;      closed_captions: 0,&#xA;      has_b_frames: 2,&#xA;      sample_aspect_ratio: &#x27;N/A&#x27;,&#xA;      display_aspect_ratio: &#x27;N/A&#x27;,&#xA;      pix_fmt: &#x27;yuv420p&#x27;,&#xA;      level: 40,&#xA;      color_range: &#x27;tv&#x27;,&#xA;      color_space: &#x27;bt709&#x27;,&#xA;      color_transfer: &#x27;bt709&#x27;,&#xA;      color_primaries: &#x27;bt709&#x27;,&#xA;      chroma_location: &#x27;left&#x27;,&#xA;      field_order: &#x27;unknown&#x27;,&#xA;      refs: 1,&#xA;      is_avc: &#x27;true&#x27;,&#xA;      nal_length_size: 4,&#xA;      id: &#x27;N/A&#x27;,&#xA;      r_frame_rate: &#x27;30000/1001&#x27;,&#xA;      avg_frame_rate: &#x27;27000/1001&#x27;,&#xA;      time_base: &#x27;1/30000&#x27;,&#xA;      start_pts: 0,&#xA;      start_time: 0,&#xA;      duration_ts: 15100,&#xA;      duration: 0.503333,&#xA;      bit_rate: 5660223,&#xA;      max_bit_rate: &#x27;N/A&#x27;,&#xA;      bits_per_raw_sample: 8,&#xA;      nb_frames: 36,&#xA;      nb_read_frames: &#x27;N/A&#x27;,&#xA;      nb_read_packets: &#x27;N/A&#x27;,&#xA;      tags: [Object],&#xA;      disposition: [Object]&#xA;    },&#xA;    {&#xA;      index: 1,&#xA;      codec_name: &#x27;aac&#x27;,&#xA;      codec_long_name: &#x27;AAC (Advanced Audio Coding)&#x27;,&#xA;      profile: &#x27;LC&#x27;,&#xA;      codec_type: &#x27;audio&#x27;,&#xA;      codec_tag_string: &#x27;mp4a&#x27;,&#xA;      codec_tag: &#x27;0x6134706d&#x27;,&#xA;      sample_fmt: &#x27;fltp&#x27;,&#xA;      sample_rate: 48000,&#xA;      channels: 2,&#xA;      channel_layout: &#x27;stereo&#x27;,&#xA;      bits_per_sample: 0,&#xA;      id: &#x27;N/A&#x27;,&#xA;      r_frame_rate: &#x27;0/0&#x27;,&#xA;      avg_frame_rate: &#x27;0/0&#x27;,&#xA;      time_base: &#x27;1/48000&#x27;,&#xA;      start_pts: 0,&#xA;      start_time: 0,&#xA;      duration_ts: 24160,&#xA;      duration: 0.503333,&#xA;      bit_rate: 248416,&#xA;      max_bit_rate: &#x27;N/A&#x27;,&#xA;      bits_per_raw_sample: &#x27;N/A&#x27;,&#xA;      nb_frames: 27,&#xA;      nb_read_frames: &#x27;N/A&#x27;,&#xA;      nb_read_packets: &#x27;N/A&#x27;,&#xA;      tags: [Object],&#xA;      disposition: [Object]&#xA;    }&#xA;  ],&#xA;  format: {&#xA;    filename: &#x27;/Users/name/images/input.mp4&#x27;,&#xA;    nb_streams: 2,&#xA;    nb_programs: 0,&#xA;    format_name: &#x27;mov,mp4,m4a,3gp,3g2,mj2&#x27;,&#xA;    format_long_name: &#x27;QuickTime / MOV&#x27;,&#xA;    start_time: 0,&#xA;    duration: 0.503333,&#xA;    size: 963879,&#xA;    bit_rate: 15319941,&#xA;    probe_score: 100,&#xA;    tags: {&#xA;      major_brand: &#x27;mp42&#x27;,&#xA;      minor_version: &#x27;1&#x27;,&#xA;      compatible_brands: &#x27;isommp41mp42&#x27;,&#xA;      creation_time: &#x27;2024-02-14T01:21:12.000000Z&#x27;&#xA;    }&#xA;  },&#xA;  chapters: []&#xA;}&#xA;

    &#xA;

    and here is from running ffprobe directly :

    &#xA;

    ffprobe &#x27;/Users/name/images/input.mp4&#x27;&#xA;ffprobe version 6.1.1 Copyright (c) 2007-2023 the FFmpeg developers&#xA;  built with Apple clang version 15.0.0 (clang-1500.1.0.2.5)&#xA;  configuration: --prefix=/opt/homebrew/Cellar/ffmpeg/6.1.1_2 --enable-shared --enable-pthreads --enable-version3 --cc=clang --host-cflags= --host-ldflags=&#x27;-Wl,-ld_classic&#x27; --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libaribb24 --enable-libbluray --enable-libdav1d --enable-libharfbuzz --enable-libjxl --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librist --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libssh --enable-libsvtav1 --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopenvino --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-videotoolbox --enable-audiotoolbox --enable-neon&#xA;  libavutil      58. 29.100 / 58. 29.100&#xA;  libavcodec     60. 31.102 / 60. 31.102&#xA;  libavformat    60. 16.100 / 60. 16.100&#xA;  libavdevice    60.  3.100 / 60.  3.100&#xA;  libavfilter     9. 12.100 /  9. 12.100&#xA;  libswscale      7.  5.100 /  7.  5.100&#xA;  libswresample   4. 12.100 /  4. 12.100&#xA;  libpostproc    57.  3.100 / 57.  3.100&#xA;Input #0, mov,mp4,m4a,3gp,3g2,mj2, from &#x27;/Users/name/images/input.mp4&#x27;:&#xA;  Metadata:&#xA;    major_brand     : mp42&#xA;    minor_version   : 1&#xA;    compatible_brands: isommp41mp42&#xA;    creation_time   : 2024-02-14T01:21:12.000000Z&#xA;  Duration: 00:00:00.50, start: 0.000000, bitrate: 15319 kb/s&#xA;  Stream #0:0[0x1](und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 1080x1920, 5660 kb/s, 26.97 fps, 29.97 tbr, 30k tbn (default)&#xA;    Metadata:&#xA;      creation_time   : 2024-02-14T01:21:12.000000Z&#xA;      handler_name    : Core Media Video&#xA;      vendor_id       : [0][0][0][0]&#xA;      encoder         : AVC Coding&#xA;  Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 248 kb/s (default)&#xA;    Metadata:&#xA;      creation_time   : 2024-02-14T01:21:12.000000Z&#xA;      handler_name    : Core Media Audio&#xA;      vendor_id       : [0][0][0][0]&#xA;

    &#xA;

    And this is my command to go from video to frames :

    &#xA;

    ffmpeg -i /Users/name/images/input.mp4 -y -f image2 /Users/name/images/frames/%d.png&#xA;

    &#xA;

    After which I convert the frames back to video with this - note that I get by seeing avg_frame_rate is 27000/1001 = 26.97302697 :

    &#xA;

    ffmpeg -r 26.973026973026972 -i /Users/name/images/frames/%d.png -y -r 26.973026973026972 -b:v 5660223k -f mp4 -pix_fmt yuv420p -t 0.503333 /Users/name/images/output.mp4&#xA;

    &#xA;

    And if I then run fluent-ffmpeg's ffmpeg.ffprobe(videoPath) I get :

    &#xA;

    metadata {&#xA;  streams: [&#xA;    {&#xA;      index: 0,&#xA;      codec_name: &#x27;h264&#x27;,&#xA;      codec_long_name: &#x27;H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10&#x27;,&#xA;      profile: &#x27;High&#x27;,&#xA;      codec_type: &#x27;video&#x27;,&#xA;      codec_tag_string: &#x27;avc1&#x27;,&#xA;      codec_tag: &#x27;0x31637661&#x27;,&#xA;      width: 1080,&#xA;      height: 1920,&#xA;      coded_width: 1080,&#xA;      coded_height: 1920,&#xA;      closed_captions: 0,&#xA;      has_b_frames: 2,&#xA;      sample_aspect_ratio: &#x27;1:1&#x27;,&#xA;      display_aspect_ratio: &#x27;9:16&#x27;,&#xA;      pix_fmt: &#x27;yuv420p&#x27;,&#xA;      level: 62,&#xA;      color_range: &#x27;unknown&#x27;,&#xA;      color_space: &#x27;unknown&#x27;,&#xA;      color_transfer: &#x27;unknown&#x27;,&#xA;      color_primaries: &#x27;unknown&#x27;,&#xA;      chroma_location: &#x27;left&#x27;,&#xA;      field_order: &#x27;unknown&#x27;,&#xA;      refs: 1,&#xA;      is_avc: &#x27;true&#x27;,&#xA;      nal_length_size: 4,&#xA;      id: &#x27;N/A&#x27;,&#xA;      r_frame_rate: &#x27;27000/1001&#x27;,&#xA;      avg_frame_rate: &#x27;27000/1001&#x27;,&#xA;      time_base: &#x27;1/27000&#x27;,&#xA;      start_pts: 0,&#xA;      start_time: 0,&#xA;      duration_ts: 14014,&#xA;      duration: 0.519037,&#xA;      bit_rate: 52138429,&#xA;      max_bit_rate: &#x27;N/A&#x27;,&#xA;      bits_per_raw_sample: 8,&#xA;      nb_frames: 14,&#xA;      nb_read_frames: &#x27;N/A&#x27;,&#xA;      nb_read_packets: &#x27;N/A&#x27;,&#xA;      tags: [Object],&#xA;      disposition: [Object]&#xA;    }&#xA;  ],&#xA;  format: {&#xA;    filename: &#x27;/Users/name/images/output.mp4&#x27;,&#xA;    nb_streams: 1,&#xA;    nb_programs: 0,&#xA;    format_name: &#x27;mov,mp4,m4a,3gp,3g2,mj2&#x27;,&#xA;    format_long_name: &#x27;QuickTime / MOV&#x27;,&#xA;    start_time: 0,&#xA;    duration: 0.52,&#xA;    size: 3383708,&#xA;    bit_rate: 52057046,&#xA;    probe_score: 100,&#xA;    tags: {&#xA;      major_brand: &#x27;isom&#x27;,&#xA;      minor_version: &#x27;512&#x27;,&#xA;      compatible_brands: &#x27;isomiso2avc1mp41&#x27;,&#xA;      encoder: &#x27;Lavf60.3.100&#x27;&#xA;    }&#xA;  },&#xA;  chapters: []&#xA;}&#xA;

    &#xA;

    and here is from running ffprobe directly :

    &#xA;

    ffprobe &#x27;/Users/name/images/output.mp4&#x27;&#xA;ffprobe version 6.1.1 Copyright (c) 2007-2023 the FFmpeg developers&#xA;  built with Apple clang version 15.0.0 (clang-1500.1.0.2.5)&#xA;  configuration: --prefix=/opt/homebrew/Cellar/ffmpeg/6.1.1_2 --enable-shared --enable-pthreads --enable-version3 --cc=clang --host-cflags= --host-ldflags=&#x27;-Wl,-ld_classic&#x27; --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libaribb24 --enable-libbluray --enable-libdav1d --enable-libharfbuzz --enable-libjxl --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librist --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libssh --enable-libsvtav1 --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopenvino --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-videotoolbox --enable-audiotoolbox --enable-neon&#xA;  libavutil      58. 29.100 / 58. 29.100&#xA;  libavcodec     60. 31.102 / 60. 31.102&#xA;  libavformat    60. 16.100 / 60. 16.100&#xA;  libavdevice    60.  3.100 / 60.  3.100&#xA;  libavfilter     9. 12.100 /  9. 12.100&#xA;  libswscale      7.  5.100 /  7.  5.100&#xA;  libswresample   4. 12.100 /  4. 12.100&#xA;  libpostproc    57.  3.100 / 57.  3.100&#xA;Input #0, mov,mp4,m4a,3gp,3g2,mj2, from &#x27;/Users/name/images/output.mp4&#x27;:&#xA;  Metadata:&#xA;    major_brand     : isom&#xA;    minor_version   : 512&#xA;    compatible_brands: isomiso2avc1mp41&#xA;    encoder         : Lavf60.3.100&#xA;  Duration: 00:00:00.52, start: 0.000000, bitrate: 52153 kb/s&#xA;  Stream #0:0[0x1](und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(progressive), 1080x1920 [SAR 1:1 DAR 9:16], 52138 kb/s, 26.97 fps, 26.97 tbr, 27k tbn (default)&#xA;    Metadata:&#xA;      handler_name    : VideoHandler&#xA;      vendor_id       : [0][0][0][0]&#xA;      encoder         : Lavc60.3.100 libx264&#xA;

    &#xA;

    This seems like it should be a fairly common scenario, but I have not been able to find examples of this, and the other questions about incorrect durations on Stack Overflow are about bigger differences (i.e. 3 seconds instead of 10 seconds : Wrong video duration when recording with ffmpeg).

    &#xA;

    Some other details :

    &#xA;

      &#xA;
    • I am running this through a Node.js script with fluent-ffmpeg, but I have also tried running the commands directly in the terminal and the result is the same.
    • &#xA;

    • I am fine with the output frames being .png / .jpg / other formats.
    • &#xA;

    • I am fine with setting this to a different frame rate than the original as long as the two output videos end up with the same duration.
    • &#xA;

    • One suspicious thing is that I set -t 0.503333 when creating the video, but it doesn't seem to work as the result video shows duration: 0.519037 / 00:00:00.52.
    • &#xA;

    &#xA;

    Thank you for any help !

    &#xA;

  • What is a Cohort Report ? A Beginner’s Guide to Cohort Analysis

    3 janvier 2024, par Erin

    Handling your user data as a single mass of numbers is rarely conducive to figuring out meaningful patterns you can use to improve your marketing campaigns.

    A cohort report (or cohort analysis) can help you quickly break down that larger audience into sequential segments and contrast and compare based on various metrics. As such, it is a great tool for unlocking more granular trends and insights — for example, identifying patterns in engagement and conversions based on the date users first interacted with your site.

    In this guide, we explain the basics of the cohort report and the best way to set one up to get the most out of it.

    What is a cohort report ?

    In a cohort report, you divide a data set into groups based on certain criteria — typically a time-based cohort metric like first purchase date — and then analyse the data across those segments, looking for patterns.

    Date-based cohort analysis is the most common approach, often creating cohorts based on the day a user completed a particular action — signed up, purchased something or visited your website. Depending on the metric you choose to measure (like return visits), the cohort report might look something like this :

    Example of a basic cohort report

    Note that this is not a universal benchmark or anything of the sort. The above is a theoretical cohort analysis based on app users who downloaded the app, tracking and comparing the retention rates as the days go by. 

    The benchmarks will be drastically different depending on the metric you’re measuring and the basis for your cohorts. For example, if you’re measuring returning visitor rates among first-time visitors to your website, expect single-digit percentages even on the second day.

    Your industry will also greatly affect what you consider positive in a cohort report. For example, if you’re a subscription SaaS, you’d expect high continued usage rates over the first week. If you sell office supplies to companies, much less so.

    What is an example of a cohort ?

    As we just mentioned, a typical cohort analysis separates users or customers by the date they first interacted with your business — in this case, they downloaded your app. Within that larger analysis, the users who downloaded it on May 3 represent a single cohort.

    Illustration of a specific cohort

    In this case, we’ve chosen behaviour and time — the app download day — to separate the user base into cohorts. That means every specific day denotes a specific cohort within the analysis.

    Diving deeper into an individual cohort may be a good idea for important holidays or promotional events like Black Friday.

    Of course, cohorts don’t have to be based on specific behaviour within certain periods. You can also create cohorts based on other dimensions :

    • Transactional data — revenue per user
    • Churn data — date of churn
    • Behavioural cohort — based on actions taken on your website, app or e-commerce store, like the number of sessions per user or specific product pages visited
    • Acquisition cohort — which channel referred the user or customer

    For more information on different cohort types, read our in-depth guide on cohort analysis.

    How to create a cohort report (and make sense of it)

    Matomo makes it easy to view and analyse different cohorts (without the privacy and legal implications of using Google Analytics).

    Here are a few different ways to set up a cohort report in Matomo, starting with our built-in cohorts report.

    Cohort reports

    With Matomo, cohort reports are automatically compiled based on the first visit date. The default metric is the percentage of returning visitors.

    Screenshot of the cohorts report in Matomo analytics

    Changing the settings allows you to create multiple variations of cohort analysis reports.

    Break down cohorts by different metrics

    The percentage of returning visits can be valuable if you’re trying to improve early engagement in a SaaS app onboarding process. But it’s far from your only option.

    You can also compare performance by conversion, revenue, bounce rate, actions per visit, average session duration or other metrics.

    Cohort metric options in Matomo analytics

    Change the time and scope of your cohort analysis

    Splitting up cohorts by single days may be useless if you don’t have a high volume of users or visitors. If the average cohort size is only a few users, you won’t be able to identify reliable patterns. 

    Matomo lets you set any time period to create your cohort analysis report. Instead of the most recent days, you can create cohorts by week, month, year or custom date ranges. 

    Date settings in the cohorts report in Matomo analytics

    Cohort sizes will depend on your customer base. Make sure each cohort is large enough to encapsulate all the customers in that cohort and not so small that you have insignificant cohorts of only a few customers. Choose a date range that gives you that without scaling it too far so you can’t identify any seasonal trends.

    Cohort analysis can be a great tool if you’ve recently changed your marketing, product offering or onboarding. Set the data range to weekly and look for any impact in conversions and revenue after the changes.

    Using the “compare to” feature, you can also do month-over-month, quarter-over-quarter or any custom date range comparisons. This approach can help you get a rough overview of your campaign’s long-term progress without doing any in-depth analysis.

    You can also use the same approach to compare different holiday seasons against each other.

    If you want to combine time cohorts with segmentation, you can run cohort reports for different subsets of visitors instead of all visitors. This can lead to actionable insights like adjusting weekend or specific seasonal promotions to improve conversion rates.

    Try Matomo for Free

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

    No credit card required

    Easily create custom cohort reports beyond the time dimension

    If you want to split your audience into cohorts by focusing on something other than time, you will need to create a custom report and choose another dimension. In Matomo, you can choose from a wide range of cohort metrics, including referrers, e-commerce signals like viewed product or product category, form submissions and more.

    Custom report options in Matomo

    Then, you can create a simple table-based report with all the insights you need by choosing the metrics you want to see. For example, you could choose average visit duration, bounce rate and other usage metrics.

    Metrics selected in a Matomo custom report

    If you want more revenue-focused insights, add metrics like conversions, add-to-cart and other e-commerce events.

    Custom reports make it easy to create cohort reports for almost any dimension. You can use any metric within demographic and behavioural analytics to create a cohort. (You can explore the complete list of our possible segmentation metrics.)

    We cover different types of custom reports (and ideas for specific marketing campaigns) in our guide on custom segmentation.

    Create your first cohort report and gain better insights into your visitors

    Cohort reports can help you identify trends and the impact of short-term marketing efforts like events and promotions.

    With Matomo cohort reports you have the power to create complex custom reports for various cohorts and segments. 

    If you’re looking for a powerful, easy-to-use web analytics solution that gives you 100% accurate data without compromising your users’ privacy, Matomo is a great fit. Get started with a 21-day free trial today. No credit card required.