Recherche avancée

Médias (91)

Autres articles (93)

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

  • HTML5 audio and video support

    13 avril 2011, par

    MediaSPIP uses HTML5 video and audio tags to play multimedia files, taking advantage of the latest W3C innovations supported by modern browsers.
    The MediaSPIP player used has been created specifically for MediaSPIP and can be easily adapted to fit in with a specific theme.
    For older browsers the Flowplayer flash fallback is used.
    MediaSPIP allows for media playback on major mobile platforms with the above (...)

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

  • FFMPEG not working from Python subprocess.Popen but works from command line

    21 novembre 2017, par Stuart Clarke

    I’m trying to run a FFMPEG script from within python 3.5.2. the FFMPEG command runs fine from the command line but fails within the python script.

    The function I use to execute the FFMPEG command is

    def ffmpeg(args):
       err = None
       command = [
           ffmpegcmd, '-y',
           '-loglevel', loglevel
       ] + args
       print("\n\n\n")
       print(command)
       print("\n\n\n")
       print(" ".join(command))
       ffmpeg = subprocess.Popen(command, stderr=subprocess.PIPE ,stdout=subprocess.PIPE, universal_newlines=True)
       while err == None:
           out, err = ffmpeg.communicate()
           time.sleep(1)
       if err and loglevel=='fatal':
           print(" ".join(command))
           raise Exception(err)
       print(err)

    The value for args is :

    ['-i', '/var/www/temp/film.mp4', '-vf', 'scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:x=(1920-iw)/2:y=(1080-ih)/2:color=black', '/var/www/temp/videoHD.mp4']

    such that the resultant command being passed to subprocess.Popen is :

    ['ffmpeg', '-y', '-loglevel', 'verbose', '-i', '/var/www/temp/film.mp4', '-vf', 'scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:x=(1920-iw)/2:y=(1080-ih)/2:color=black', '/var/www/temp/videoHD.mp4']

    The value of loglevel is verbose only for troubleshooting but is intended to run as fatal. There are also some print commands only in place for troubleshooting.

    The reason for wanting to increase the resolution is so that it can be combined later with higher resolution videos.

    The result when running from within python is :

    ffmpeg version 3.3.4-2~16.04.york0 Copyright (c) 2000-2017 the FFmpeg developers
     built with gcc 5.4.0 (Ubuntu 5.4.0-6ubuntu1~16.04.4) 20160609
     configuration: --prefix=/usr --extra-version='2~16.04.york0' --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --enable-gpl --disable-stripping --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmp3lame --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-omx --enable-openal --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libopencv --enable-libx264 --enable-shared
     libavutil      55. 58.100 / 55. 58.100
     libavcodec     57. 89.100 / 57. 89.100
     libavformat    57. 71.100 / 57. 71.100
     libavdevice    57.  6.100 / 57.  6.100
     libavfilter     6. 82.100 /  6. 82.100
     libavresample   3.  5.  0 /  3.  5.  0
     libswscale      4.  6.100 /  4.  6.100
     libswresample   2.  7.100 /  2.  7.100
     libpostproc    54.  5.100 / 54.  5.100
    [h264 @ 0x7f741a37a560] Reinit context to 640x368, pix_fmt: yuv420p
    Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/var/www/temp/film.mp4':
     Metadata:
       major_brand     : isom
       minor_version   : 512
       compatible_brands: isomiso2avc1mp41
       encoder         : Lavf57.71.100
     Duration: 00:06:19.80, start: 0.000000, bitrate: 451 kb/s
       Stream #0:0(und): Video: h264 (High), 1 reference frame (avc1 / 0x31637661), yuv420p(left), 640x358 (640x368), 313 kb/s, 30 fps, 30 tbr, 15360 tbn, 60 tbc (default)
       Metadata:
         handler_name    : VideoHandler
       Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s (default)
       Metadata:
         handler_name    : SoundHandler
    Stream mapping:
     Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
     Stream #0:1 -> #0:1 (aac (native) -> aac (native))
    Press [q] to stop, [?] for help
    [h264 @ 0x7f741a3bc700] Reinit context to 640x368, pix_fmt: yuv420p
    [graph_1_in_0_1 @ 0x7f741a5315e0] tb:1/48000 samplefmt:fltp samplerate:48000 chlayout:0x3
    [Parsed_scale_0 @ 0x7f741a54e000] w:1920 h:1080 flags:'bicubic' interl:0
    [graph 0 input from stream 0:0 @ 0x7f741a54f6a0] w:640 h:358 pixfmt:yuv420p tb:1/15360 fr:30/1 sar:0/1 sws_param:flags=2
    [Parsed_scale_0 @ 0x7f741a54e000] w:640 h:358 fmt:yuv420p sar:0/1 -> w:1920 h:1074 fmt:yuv420p sar:0/1 flags:0x4
    [Parsed_pad_1 @ 0x7f741a54eac0] w:1920 h:1074 -> w:1920 h:1080 x:0 y:2 color:0x000000FF
    [libx264 @ 0x7f741a5509e0] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 AVX2 LZCNT BMI2
    [libx264 @ 0x7f741a5509e0] profile High, level 4.0
    [libx264 @ 0x7f741a5509e0] 264 - core 148 r2795 aaa9aa8 - H.264/MPEG-4 AVC codec - Copyleft 2003-2017 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=6 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
    Output #0, mp4, to '/var/www/temp/videoHD.mp4':
     Metadata:
       major_brand     : isom
       minor_version   : 512
       compatible_brands: isomiso2avc1mp41
       encoder         : Lavf57.71.100
       Stream #0:0(und): Video: h264 (libx264), 1 reference frame ([33][0][0][0] / 0x0021), yuv420p(left), 1920x1080, q=-1--1, 30 fps, 15360 tbn, 30 tbc (default)
       Metadata:
         handler_name    : VideoHandler
         encoder         : Lavc57.89.100 libx264
       Side data:
         cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: -1
       Stream #0:1(und): Audio: aac (LC) ([64][0][0][0] / 0x0040), 48000 Hz, stereo, fltp, delay 1024, 128 kb/s (default)
       Metadata:
         handler_name    : SoundHandler
         encoder         : Lavc57.89.100 aac

    This results in a file with no content.

    When I run the command from the command line I need to add single quotes around the -vf video filters scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:x=(1920-iw)/2:y=(1080-ih)/2:color=black so the whole command becomes :

    ffmpeg -y -loglevel verbose -i /var/www/temp/film.mp4 -vf 'scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:x=(1920-iw)/2:y=(1080-ih)/2:color=black' /var/www/temp/videoHD.mp4

    Running this command gives the required result.

    ffmpeg version 3.3.4-2~16.04.york0 Copyright (c) 2000-2017 the FFmpeg developers
     built with gcc 5.4.0 (Ubuntu 5.4.0-6ubuntu1~16.04.4) 20160609
     configuration: --prefix=/usr --extra-version='2~16.04.york0' --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --enable-gpl --disable-stripping --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmp3lame --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-omx --enable-openal --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libopencv --enable-libx264 --enable-shared
     libavutil      55. 58.100 / 55. 58.100
     libavcodec     57. 89.100 / 57. 89.100
     libavformat    57. 71.100 / 57. 71.100
     libavdevice    57.  6.100 / 57.  6.100
     libavfilter     6. 82.100 /  6. 82.100
     libavresample   3.  5.  0 /  3.  5.  0
     libswscale      4.  6.100 /  4.  6.100
     libswresample   2.  7.100 /  2.  7.100
     libpostproc    54.  5.100 / 54.  5.100
    [h264 @ 0x7f3a55c17560] Reinit context to 640x368, pix_fmt: yuv420p
    Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/var/www/temp/film.mp4':
     Metadata:
       major_brand     : isom
       minor_version   : 512
       compatible_brands: isomiso2avc1mp41
       encoder         : Lavf57.71.100
     Duration: 00:06:19.80, start: 0.000000, bitrate: 451 kb/s
       Stream #0:0(und): Video: h264 (High), 1 reference frame (avc1 / 0x31637661), yuv420p(left), 640x358 (640x368), 313 kb/s, 30 fps, 30 tbr, 15360 tbn, 60 tbc (default)
       Metadata:
         handler_name    : VideoHandler
       Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s (default)
       Metadata:
         handler_name    : SoundHandler
    Stream mapping:
     Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
     Stream #0:1 -> #0:1 (aac (native) -> aac (native))
    Press [q] to stop, [?] for help
    [h264 @ 0x7f3a55c59700] Reinit context to 640x368, pix_fmt: yuv420p
    [graph_1_in_0_1 @ 0x7f3a55dce5e0] tb:1/48000 samplefmt:fltp samplerate:48000 chlayout:0x3
    [Parsed_scale_0 @ 0x7f3a55deb000] w:1920 h:1080 flags:'bicubic' interl:0
    [graph 0 input from stream 0:0 @ 0x7f3a55dec6a0] w:640 h:358 pixfmt:yuv420p tb:1/15360 fr:30/1 sar:0/1 sws_param:flags=2
    [Parsed_scale_0 @ 0x7f3a55deb000] w:640 h:358 fmt:yuv420p sar:0/1 -> w:1920 h:1074 fmt:yuv420p sar:0/1 flags:0x4
    [Parsed_pad_1 @ 0x7f3a55debac0] w:1920 h:1074 -> w:1920 h:1080 x:0 y:2 color:0x000000FF
    [libx264 @ 0x7f3a55ded9e0] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 AVX2 LZCNT BMI2
    [libx264 @ 0x7f3a55ded9e0] profile High, level 4.0
    [libx264 @ 0x7f3a55ded9e0] 264 - core 148 r2795 aaa9aa8 - H.264/MPEG-4 AVC codec - Copyleft 2003-2017 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=6 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
    Output #0, mp4, to '/var/www/temp/videoHD.mp4':
     Metadata:
       major_brand     : isom
       minor_version   : 512
       compatible_brands: isomiso2avc1mp41
       encoder         : Lavf57.71.100
       Stream #0:0(und): Video: h264 (libx264), 1 reference frame ([33][0][0][0] / 0x0021), yuv420p(left), 1920x1080, q=-1--1, 30 fps, 15360 tbn, 30 tbc (default)
       Metadata:
         handler_name    : VideoHandler
         encoder         : Lavc57.89.100 libx264
       Side data:
         cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: -1
       Stream #0:1(und): Audio: aac (LC) ([64][0][0][0] / 0x0040), 48000 Hz, stereo, fltp, delay 1024, 128 kb/s (default)
       Metadata:
         handler_name    : SoundHandler
         encoder         : Lavc57.89.100 aac
    frame=   46 fps=0.0 q=0.0 size=       0kB time=00:00:01.62 bitrate=   0.0kbits/s
    frame=   59 fps= 47 q=29.0 size=     116kB time=00:00:02.04 bitrate= 464.8kbits/
    frame=   74 fps= 41 q=29.0 size=     223kB time=00:00:02.56 bitrate= 714.8kbits/
    frame=   87 fps= 35 q=29.0 size=     344kB time=00:00:02.98 bitrate= 942.4kbits/
    frame=   98 fps= 33 q=29.0 size=     427kB time=00:00:03.34 bitrate=1043.4kbits/
       blah
       blah
       blah
    frame=11347 fps= 21 q=29.0 size=   97550kB time=00:06:18.32 bitrate=2112.3kbits/
    frame=11363 fps= 21 q=29.0 size=   97713kB time=00:06:18.85 bitrate=2112.8kbits/
    frame=11380 fps= 21 q=29.0 size=   97795kB time=00:06:19.41 bitrate=2111.5kbits/
    No more output streams to write to, finishing.
    frame=11392 fps= 21 q=-1.0 Lsize=   98519kB time=00:06:19.77 bitrate=2125.1kbits/s speed=0.69x    
    video:92124kB audio:5986kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.416313%
    Input file #0 (/var/www/temp/film.mp4):
     Input stream #0:0 (video): 11392 packets read (14892948 bytes); 11392 frames decoded;
     Input stream #0:1 (audio): 17803 packets read (6112540 bytes); 17802 frames decoded (18229248 samples);
     Total: 29195 packets (21005488 bytes) demuxed
    Output file #0 (/var/www/temp/videoHD.mp4):
     Output stream #0:0 (video): 11392 frames encoded; 11392 packets muxed (94334785 bytes);
     Output stream #0:1 (audio): 17802 frames encoded (18229248 samples); 17803 packets muxed (6129981 bytes);
     Total: 29195 packets (100464766 bytes) muxed
    [libx264 @ 0x7f3a55ded9e0] frame I:74    Avg QP:19.08  size: 51540
    [libx264 @ 0x7f3a55ded9e0] frame P:3506  Avg QP:21.34  size: 19348
    [libx264 @ 0x7f3a55ded9e0] frame B:7812  Avg QP:24.07  size:  2904
    [libx264 @ 0x7f3a55ded9e0] consecutive B-frames:  1.3% 20.2%  4.6% 73.9%
    [libx264 @ 0x7f3a55ded9e0] mb I  I16..4: 19.7% 73.6%  6.7%
    [libx264 @ 0x7f3a55ded9e0] mb P  I16..4:  3.2%  6.4%  0.1%  P16..4: 52.5%  7.6%  2.6%  0.0%  0.0%    skip:27.6%
    [libx264 @ 0x7f3a55ded9e0] mb B  I16..4:  0.2%  0.2%  0.0%  B16..8: 23.2%  0.4%  0.0%  direct: 0.5%  skip:75.5%  L0:51.8% L1:46.6% BI: 1.6%
    [libx264 @ 0x7f3a55ded9e0] 8x8 transform intra:66.4% inter:94.0%
    [libx264 @ 0x7f3a55ded9e0] coded y,uvDC,uvAC intra: 33.6% 53.4% 7.3% inter: 5.3% 14.2% 0.0%
    [libx264 @ 0x7f3a55ded9e0] i16 v,h,dc,p: 22% 27%  5% 46%
    [libx264 @ 0x7f3a55ded9e0] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 29% 19% 20%  4%  7%  7%  7%  5%  4%
    [libx264 @ 0x7f3a55ded9e0] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 31% 28% 11%  3%  9%  7%  6%  3%  2%
    [libx264 @ 0x7f3a55ded9e0] i8c dc,h,v,p: 49% 21% 20% 10%
    [libx264 @ 0x7f3a55ded9e0] Weighted P-Frames: Y:0.5% UV:0.1%
    [libx264 @ 0x7f3a55ded9e0] ref P L0: 63.4%  8.9% 21.4%  6.3%  0.0%
    [libx264 @ 0x7f3a55ded9e0] ref B L0: 89.3%  9.1%  1.6%
    [libx264 @ 0x7f3a55ded9e0] ref B L1: 98.1%  1.9%
    [libx264 @ 0x7f3a55ded9e0] kb/s:1987.38
    [aac @ 0x7f3a55deee80] Qavg: 1160.814

    and the resulting video is fine.

    Any ideas ?

    Cheers,

    Stu

    Edit

    It was suggested that I use a new function to do much the same thing. So I added the following function and used it for the command that I’m having trouble with :

    def ffmpegPro(args):
       err = None
       for i, arg in enumerate(args):
           if(" " in arg or "(" in arg or "[" in arg):
               args[i] = "\"" + arg + "\""
       command = [
           ffmpegcmd, '-y',
           '-loglevel', loglevel
       ] + args
       commandStr = " ".join(command)
       print("\n\n\n")
       print(command)
       print("\n\n\n")
       print(commandStr)
       ffmpeg = subprocess.Popen(commandStr, stderr=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True, shell=True)
       while err == None:
           out, err = ffmpeg.communicate()
           time.sleep(1)
       if ffmpeg.returncode == 0 and all([os.path.exists(f) for f in (videoStorage['data_small'], videoStorage['data_big'])]):
           print("Job done.")
       else:
           print("ERROR")
           print(err)

    The resulting command can now be used in python or at the command line without needing to be changed at all. The command is :

    ffmpeg -y -loglevel verbose -i /var/www/temp/film.mp4 -vf "scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:x=(1920-iw)/2:y=(1080-ih)/2:color=black" /var/www/temp/videoHD.mp4

    The result when executed in python is

    ffmpeg version 3.3.4-2~16.04.york0 Copyright (c) 2000-2017 the FFmpeg developers
     built with gcc 5.4.0 (Ubuntu 5.4.0-6ubuntu1~16.04.4) 20160609
     configuration: --prefix=/usr --extra-version='2~16.04.york0' --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --enable-gpl --disable-stripping --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmp3lame --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-omx --enable-openal --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libopencv --enable-libx264 --enable-shared
     libavutil      55. 58.100 / 55. 58.100
     libavcodec     57. 89.100 / 57. 89.100
     libavformat    57. 71.100 / 57. 71.100
     libavdevice    57.  6.100 / 57.  6.100
     libavfilter     6. 82.100 /  6. 82.100
     libavresample   3.  5.  0 /  3.  5.  0
     libswscale      4.  6.100 /  4.  6.100
     libswresample   2.  7.100 /  2.  7.100
     libpostproc    54.  5.100 / 54.  5.100
    [h264 @ 0x7fb75053d560] Reinit context to 640x368, pix_fmt: yuv420p
    Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/var/www/temp/film.mp4':
     Metadata:
       major_brand     : isom
       minor_version   : 512
       compatible_brands: isomiso2avc1mp41
       encoder         : Lavf57.71.100
     Duration: 00:06:19.80, start: 0.000000, bitrate: 451 kb/s
       Stream #0:0(und): Video: h264 (High), 1 reference frame (avc1 / 0x31637661), yuv420p(left), 640x358 (640x368), 313 kb/s, 30 fps, 30 tbr, 15360 tbn, 60 tbc (default)
       Metadata:
         handler_name    : VideoHandler
       Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s (default)
       Metadata:
         handler_name    : SoundHandler
    Stream mapping:
     Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
     Stream #0:1 -> #0:1 (aac (native) -> aac (native))
    Press [q] to stop, [?] for help
    [h264 @ 0x7fb75057f700] Reinit context to 640x368, pix_fmt: yuv420p
    [graph_1_in_0_1 @ 0x7fb7506f45e0] tb:1/48000 samplefmt:fltp samplerate:48000 chlayout:0x3
    [Parsed_scale_0 @ 0x7fb750711000] w:1920 h:1080 flags:'bicubic' interl:0
    [graph 0 input from stream 0:0 @ 0x7fb7507126a0] w:640 h:358 pixfmt:yuv420p tb:1/15360 fr:30/1 sar:0/1 sws_param:flags=2
    [Parsed_scale_0 @ 0x7fb750711000] w:640 h:358 fmt:yuv420p sar:0/1 -> w:1920 h:1074 fmt:yuv420p sar:0/1 flags:0x4
    [Parsed_pad_1 @ 0x7fb750711ac0] w:1920 h:1074 -> w:1920 h:1080 x:0 y:2 color:0x000000FF
    [libx264 @ 0x7fb7507139e0] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 AVX2 LZCNT BMI2
    [libx264 @ 0x7fb7507139e0] profile High, level 4.0
    [libx264 @ 0x7fb7507139e0] 264 - core 148 r2795 aaa9aa8 - H.264/MPEG-4 AVC codec - Copyleft 2003-2017 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=6 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
    Output #0, mp4, to '/var/www/temp/videoHD.mp4':
     Metadata:
       major_brand     : isom
       minor_version   : 512
       compatible_brands: isomiso2avc1mp41
       encoder         : Lavf57.71.100
       Stream #0:0(und): Video: h264 (libx264), 1 reference frame ([33][0][0][0] / 0x0021), yuv420p(left), 1920x1080, q=-1--1, 30 fps, 15360 tbn, 30 tbc (default)
       Metadata:
         handler_name    : VideoHandler
         encoder         : Lavc57.89.100 libx264
       Side data:
         cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: -1
       Stream #0:1(und): Audio: aac (LC) ([64][0][0][0] / 0x0040), 48000 Hz, stereo, fltp, delay 1024, 128 kb/s (default)
       Metadata:
         handler_name    : SoundHandler
         encoder         : Lavc57.89.100 aac
    Killed

    Note the Killed at the end. Is this significant and why is it only happening when executed in the script ?

    Here is the output from the command line which results in a successful video file.

    ffmpeg version 3.3.4-2~16.04.york0 Copyright (c) 2000-2017 the FFmpeg developers
     built with gcc 5.4.0 (Ubuntu 5.4.0-6ubuntu1~16.04.4) 20160609
     configuration: --prefix=/usr --extra-version='2~16.04.york0' --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --enable-gpl --disable-stripping --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmp3lame --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-omx --enable-openal --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libopencv --enable-libx264 --enable-shared
     libavutil      55. 58.100 / 55. 58.100
     libavcodec     57. 89.100 / 57. 89.100
     libavformat    57. 71.100 / 57. 71.100
     libavdevice    57.  6.100 / 57.  6.100
     libavfilter     6. 82.100 /  6. 82.100
     libavresample   3.  5.  0 /  3.  5.  0
     libswscale      4.  6.100 /  4.  6.100
     libswresample   2.  7.100 /  2.  7.100
     libpostproc    54.  5.100 / 54.  5.100
    [h264 @ 0x7fb52cfb3560] Reinit context to 640x368, pix_fmt: yuv420p
    Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/var/www/temp/film.mp4':
     Metadata:
       major_brand     : isom
       minor_version   : 512
       compatible_brands: isomiso2avc1mp41
       encoder         : Lavf57.71.100
     Duration: 00:06:19.80, start: 0.000000, bitrate: 451 kb/s
       Stream #0:0(und): Video: h264 (High), 1 reference frame (avc1 / 0x31637661), yuv420p(left), 640x358 (640x368), 313 kb/s, 30 fps, 30 tbr, 15360 tbn, 60 tbc (default)
       Metadata:
         handler_name    : VideoHandler
       Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s (default)
       Metadata:
         handler_name    : SoundHandler
    Stream mapping:
     Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
     Stream #0:1 -> #0:1 (aac (native) -> aac (native))
    Press [q] to stop, [?] for help
    [h264 @ 0x7fb52cff5700] Reinit context to 640x368, pix_fmt: yuv420p
    [graph_1_in_0_1 @ 0x7fb52d16a5e0] tb:1/48000 samplefmt:fltp samplerate:48000 chlayout:0x3
    [Parsed_scale_0 @ 0x7fb52d187000] w:1920 h:1080 flags:'bicubic' interl:0
    [graph 0 input from stream 0:0 @ 0x7fb52d1886a0] w:640 h:358 pixfmt:yuv420p tb:1/15360 fr:30/1 sar:0/1 sws_param:flags=2
    [Parsed_scale_0 @ 0x7fb52d187000] w:640 h:358 fmt:yuv420p sar:0/1 -> w:1920 h:1074 fmt:yuv420p sar:0/1 flags:0x4
    [Parsed_pad_1 @ 0x7fb52d187ac0] w:1920 h:1074 -> w:1920 h:1080 x:0 y:2 color:0x000000FF
    [libx264 @ 0x7fb52d1899e0] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 AVX2 LZCNT BMI2
    [libx264 @ 0x7fb52d1899e0] profile High, level 4.0
    [libx264 @ 0x7fb52d1899e0] 264 - core 148 r2795 aaa9aa8 - H.264/MPEG-4 AVC codec - Copyleft 2003-2017 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=6 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
    Output #0, mp4, to '/var/www/temp/videoHD.mp4':
     Metadata:
       major_brand     : isom
       minor_version   : 512
       compatible_brands: isomiso2avc1mp41
       encoder         : Lavf57.71.100
       Stream #0:0(und): Video: h264 (libx264), 1 reference frame ([33][0][0][0] / 0x0021), yuv420p(left), 1920x1080, q=-1--1, 30 fps, 15360 tbn, 30 tbc (default)
       Metadata:
         handler_name    : VideoHandler
         encoder         : Lavc57.89.100 libx264
       Side data:
         cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: -1
       Stream #0:1(und): Audio: aac (LC) ([64][0][0][0] / 0x0040), 48000 Hz, stereo, fltp, delay 1024, 128 kb/s (default)
       Metadata:
         handler_name    : SoundHandler
         encoder         : Lavc57.89.100 aac
    frame=   47 fps=0.0 q=0.0 size=       0kB time=00:00:01.66 bitrate=   0.0kbits/s
    frame=   59 fps= 41 q=29.0 size=     116kB time=00:00:02.04 bitrate= 464.8kbits/
    frame=   71 fps= 35 q=29.0 size=     201kB time=00:00:02.45 bitrate= 671.3kbits/
    frame=   80 fps= 31 q=29.0 size=     276kB time=00:00:02.75 bitrate= 822.0kbits/
       Blah
       Blah
       Blah
    frame=11337 fps= 21 q=29.0 size=   97503kB time=00:06:17.98 bitrate=2113.2kbits/
    frame=11351 fps= 21 q=26.0 size=   97572kB time=00:06:18.45 bitrate=2112.1kbits/
    frame=11371 fps= 21 q=29.0 size=   97745kB time=00:06:19.11 bitrate=2112.1kbits/
    frame=11390 fps= 21 q=29.0 size=   97852kB time=00:06:19.73 bitrate=2111.0kbits/
    No more output streams to write to, finishing.
    frame=11392 fps= 21 q=-1.0 Lsize=   98519kB time=00:06:19.77 bitrate=2125.1kbits/s speed=0.688x    
    video:92124kB audio:5986kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.416313%
    Input file #0 (/var/www/temp/film.mp4):
     Input stream #0:0 (video): 11392 packets read (14892948 bytes); 11392 frames decoded;
     Input stream #0:1 (audio): 17803 packets read (6112540 bytes); 17802 frames decoded (18229248 samples);
     Total: 29195 packets (21005488 bytes) demuxed
    Output file #0 (/var/www/temp/videoHD.mp4):
     Output stream #0:0 (video): 11392 frames encoded; 11392 packets muxed (94334785 bytes);
     Output stream #0:1 (audio): 17802 frames encoded (18229248 samples); 17803 packets muxed (6129981 bytes);
     Total: 29195 packets (100464766 bytes) muxed
    [libx264 @ 0x7fb52d1899e0] frame I:74    Avg QP:19.08  size: 51540
    [libx264 @ 0x7fb52d1899e0] frame P:3506  Avg QP:21.34  size: 19348
    [libx264 @ 0x7fb52d1899e0] frame B:7812  Avg QP:24.07  size:  2904
    [libx264 @ 0x7fb52d1899e0] consecutive B-frames:  1.3% 20.2%  4.6% 73.9%
    [libx264 @ 0x7fb52d1899e0] mb I  I16..4: 19.7% 73.6%  6.7%
    [libx264 @ 0x7fb52d1899e0] mb P  I16..4:  3.2%  6.4%  0.1%  P16..4: 52.5%  7.6%  2.6%  0.0%  0.0%    skip:27.6%
    [libx264 @ 0x7fb52d1899e0] mb B  I16..4:  0.2%  0.2%  0.0%  B16..8: 23.2%  0.4%  0.0%  direct: 0.5%  skip:75.5%  L0:51.8% L1:46.6% BI: 1.6%
    [libx264 @ 0x7fb52d1899e0] 8x8 transform intra:66.4% inter:94.0%
    [libx264 @ 0x7fb52d1899e0] coded y,uvDC,uvAC intra: 33.6% 53.4% 7.3% inter: 5.3% 14.2% 0.0%
    [libx264 @ 0x7fb52d1899e0] i16 v,h,dc,p: 22% 27%  5% 46%
    [libx264 @ 0x7fb52d1899e0] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 29% 19% 20%  4%  7%  7%  7%  5%  4%
    [libx264 @ 0x7fb52d1899e0] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 31% 28% 11%  3%  9%  7%  6%  3%  2%
    [libx264 @ 0x7fb52d1899e0] i8c dc,h,v,p: 49% 21% 20% 10%
    [libx264 @ 0x7fb52d1899e0] Weighted P-Frames: Y:0.5% UV:0.1%
    [libx264 @ 0x7fb52d1899e0] ref P L0: 63.4%  8.9% 21.4%  6.3%  0.0%
    [libx264 @ 0x7fb52d1899e0] ref B L0: 89.3%  9.1%  1.6%
    [libx264 @ 0x7fb52d1899e0] ref B L1: 98.1%  1.9%
    [libx264 @ 0x7fb52d1899e0] kb/s:1987.38
    [aac @ 0x7fb52d18ae80] Qavg: 1160.814

    Any more ideas why this is being handled differently in python as opposed to the command line ?

    I’m believe this is a version issue and that is why the below answer did not work for me, things were fine before I upgraded but since then a lot of things have been playing up. I upgraded both ffmpeg and python versions and don’t really want to go back if it can be avoided.

    Thanks,

    Stu

  • A Guide to GDPR Sensitive Personal Data

    13 mai 2024, par Erin

    The General Data Protection Regulation (GDPR) is one of the world’s most stringent data protection laws. It provides a legal framework for collection and processing of the personal data of EU individuals.

    The GDPR distinguishes between “special categories of personal data” (also referred to as “sensitive”) and other personal data and imposes stricter requirements on collection and processing of sensitive data. Understanding these differences will help your company comply with the requirements and avoid heavy penalties.

    In this article, we’ll explain what personal data is considered “sensitive” according to the GDPR. We’ll also examine how a web analytics solution like Matomo can help you maintain compliance.

    What is sensitive personal data ?

    The following categories of data are treated as sensitive :

      1. Personal data revealing :
        • Racial or ethnic origin ;
        • Political opinions ;
        • Religious or philosophical beliefs ;
        • Trade union membership ;
      2. Genetic and biometric data ;
      3. Data concerning a person’s :
        • Health ; or
        • Sex life or sexual orientation.
    Examples of GDPR Sensitive Personal Data

    Sensitive vs. non-sensitive personal data : What’s the difference ?

    While both categories include information about an individual, sensitive data is seen as more private, or requiring a greater protection. 

    Sensitive data often carries a higher degree of risk and harm to the data subject, if the data is exposed. For example, a data breach exposing health records could lead to discrimination for the individuals involved. An insurance company could use the information to increase premiums or deny coverage. 

    In contrast, personal data like name or gender is considered less sensitive because it doesn’t carry the same degree of harm as sensitive data. 

    Unauthorised access to someone’s name alone is less likely to harm them or infringe on their fundamental rights and freedoms than an unauthorised access to their health records or biometric data. Note that financial information (e.g. credit card details) does not fall into the special categories of data.

    Table displaying different sensitive data vs non-sensitive data

    Legality of processing

    Under the GDPR, both sensitive and nonsensitive personal data are protected. However, the rules and conditions for processing sensitive data are more stringent.

    Article 6 deals with processing of non-sensitive data and it states that processing is lawful if one of the six lawful bases for processing applies. 

    In contrast, Art. 9 of the GDPR states that processing of sensitive data is prohibited as a rule, but provides ten exceptions. 

    It is important to note that the lawful bases in Art. 6 are not the same as exceptions in Art. 9. For example, while performance of a contract or legitimate interest of the controller are a lawful basis for processing non-sensitive personal data, they are not included as an exception in Art. 9. What follows is that controllers are not permitted to process sensitive data on the basis of contract or legitimate interest. 

    The exceptions where processing of sensitive personal data is permitted (subject to additional requirements) are : 

    • Explicit consent : The individual has given explicit consent to processing their sensitive personal data for specified purpose(s), except where an EU member state prohibits such consent. See below for more information about explicit consent. 
    • Employment, social security or social protection : Processing sensitive data is necessary to perform tasks under employment, social security or social protection law.
    • Vital interests : Processing sensitive data is necessary to protect the interests of a data subject or if the individual is physically or legally incapable of consenting. 
    • Non-for-profit bodies : Foundations, associations or nonprofits with a political, philosophical, religious or trade union aim may process the sensitive data of their members or those they are in regular contact with, in connection with their purposes (and no disclosure of the data is permitted outside the organisation, without the data subject’s consent).
    • Made public : In some cases, it may be permissible to process the sensitive data of a data subject if the individual has already made it public and accessible. 
    • Legal claims : Processing sensitive data is necessary to establish, exercise or defend legal claims, including legal or in court proceedings.
    • Public interest : Processing is necessary for reasons of substantial public interest, like preventing unlawful acts or protecting the public.
    • Health or social care : Processing special category data is necessary for : preventative or occupational medicine, providing health and social care, medical diagnosis or managing healthcare systems.
    • Public health : It is permissible to process sensitive data for public health reasons, like protecting against cross-border threats to health or ensuring the safety of medicinal products or medical devices. 
    • Archiving, research and statistics : You may process sensitive data if it’s done for archiving purposes in the public interest, scientific or historical research purposes or statistical purposes.

    In addition, you must adhere to all data handling requirements set by the GDPR.

    Important : Note that for any data sent that you are processing, you always need to identify a lawful basis under Art. 6. In addition, if the data sent contains sensitive data, you must comply with Art. 9.

    Explicit consent

    While consent is a valid lawful basis for processing non-sensitive personal data, controllers are permitted to process sensitive data only with an “explicit consent” of the data subject.

    The GDPR does not define “explicit” consent, but it is accepted that it must meet all Art. 7 conditions for consent, at a higher threshold. To be “explicit” a consent requires a clear statement (oral or written) of the data subject. Consent inferred from the data subject’s actions does not meet the threshold. 

    The controller must retain records of the explicit consent and provide appropriate consent withdrawal method to allow the data subject to exercise their rights.

    Examples of compliant and non-compliant sensitive data processing

    Here are examples of when you can and can’t process sensitive data :

    • When you can process sensitive data : A doctor logs sensitive data about a patient, including their name, symptoms and medicine prescribed. The hospital can process this data to provide appropriate medical care to their patients. An IoT device and software manufacturer processes their customers’ health data based on explicit consent of each customer. 
    • When you can’t process sensitive data : One example is when you don’t have explicit consent from a data subject. Another is when there’s no lawful basis for processing it or you are collecting personal data you simply do not need. For example, you don’t need your customer’s ethnic origin to fulfil an online order.

    Other implications of processing sensitive data

    If you process sensitive data, especially on a large scale, GDPR imposes additional requirements, such as having Data Privacy Impact Assessments, appointing Data Protection Officers and EU Representatives, if you are a controller based outside the EU.

    Penalties for GDPR non-compliance

    Mishandling sensitive data (or processing it when you’re not allowed to) can result in huge penalties. There are two tiers of GDPR fines :

    • €10 million or 2% of a company’s annual revenue for less severe infringements
    • €20 million or 4% of a company’s annual revenue for more severe infringements

    In the first half of 2023 alone, fines imposed in the EU due to GDPR violations exceeded €1.6 billion, up from €73 million in 2019.

    Examples of high-profile violations in the last few years include :

    • Amazon : The Luxembourg National Commission fined the retail giant with a massive $887 million fine in 2021 for not processing personal data per the GDPR. 
    • Google : The National Data Protection Commission (CNIL) fined Google €50 million for not getting proper consent to display personalised ads.
    • H&M : The Hamburg Commissioner for Data Protection and Freedom of Information hit the multinational clothing company with a €35.3 million fine in 2020 for unlawfully gathering and storing employees’ data in its service centre.

    One of the criteria that affects the severity of a fine is “data category” — the type of personal data being processed. Companies need to take extra precautions with sensitive data, or they risk receiving more severe penalties.

    What’s more, GDPR violations can negatively affect your brand’s reputation and cause you to lose business opportunities from consumers concerned about your data practices. 76% of consumers indicated they wouldn’t buy from companies they don’t trust with their personal data.

    Organisations should lay out their data practices in simple terms and make this information easily accessible so customers know how their data is being handled.

    Get started with GDPR-compliant web analytics

    The GDPR offers a framework for securing and protecting personal data. But it also distinguishes between sensitive and non-sensitive data. Understanding these differences and applying the lawful basis for processing this data type will help ensure compliance.

    Looking for a GDPR-compliant web analytics solution ?

    At Matomo, we take data privacy seriously. 

    Our platform ensures 100% data ownership, putting you in complete control of your data. Unlike other web analytics solutions, your data remains solely yours and isn’t sold or auctioned off to advertisers. 

    Additionally, with Matomo, you can be confident in the accuracy of the insights you receive, as we provide reliable, unsampled data.

    Matomo also fully complies with GDPR and other data privacy laws like CCPA, LGPD and more.

    Start your 21-day free trial today ; no credit card required. 

    Disclaimer

    We are not lawyers and don’t claim to be. The information provided here is to help give an introduction to GDPR. We encourage every business and website to take data privacy seriously and discuss these issues with your lawyer if you have any concerns.

  • B2B Marketing Attribution Guide : How to Master It in 2024

    21 mai 2024, par Erin

    The last thing you want is to invest your advertising dollars in channels, campaigns and ads that don’t work. But B2B marketing attribution — figuring out which marketing efforts drive revenue — is far from easy.

    With longer sales funnels and multiple people from the same company involved in the same sales process, B2B (business-to-business) is a different ballgame from B2C (business-to-consumer) marketing.

    In this guide, we break down what B2B marketing attribution is, how it’s different, which tools you can use to set it up and the best practices.

    What is B2B marketing attribution ?

    Marketing attribution in B2B companies is about figuring out where your high-value leads come from — nailing down long customer journeys across many different touchpoints.

    Illustration of attributing a multi-person customer journey

    The goal is to determine which campaigns and content contributed to various parts of the customer journey. It’s a complex process that needs a reliable, privacy-focused web analytics tool and a CRM that integrates with it.

    This process significantly differs from traditional marketing attribution, where you focus more on short sales cycles from individual customers. With multiple contributing decision makers, B2B attribution requires more robust systems.

    What makes marketing attribution different for B2B ?

    The key differences between B2B and B2C marketing attribution are a longer sales funnel and more people involved in the sales process.

    The B2B sales funnel is significantly longer and more complex

    The typical B2C sales funnel is often broken down into four simple stages :

    1. Awareness : when a prospect first finds out about your product or brand
    2. Interest : where a prospect starts to learn about the benefits of your product
    3. Desire : when a prospect understands that they need your product
    4. Action : the actual process of closing the sale

    Even the most simplified B2B sales funnel includes several key stages.

    5 stages of the B2B customer journey.

    Here’s a brief overview of each :

    1. Awareness : Buyers recognise they have a problem and start looking for solutions. Stand out with blog posts, social media updates, ebooks and whitepapers.
    2. Consideration : Buyers are aware of your company and are comparing options. Provide product demos, webinars and case studies to address their concerns and build trust.
    3. Conversion : Buyers have chosen your product or company. Offer live demos, customer service, case studies and testimonials to finalise the purchase.
    4. Loyalty : Buyers have made a purchase and are now customers. Nurture relationships with thank you emails, follow-ups, how-tos, reward programs and surveys to encourage repeat business.
    5. Advocacy : Loyal customers become advocates, promoting your brand to others. Encourage this with surveys, testimonial requests and a referral program.

    A longer sales cycle typically involves not only more touchpoints but also extended decision-making processes.

    More teams are involved in the marketing and sales process

    The last differentiation in B2B attribution is the number of people involved. Instead of clear-cut sales and marketing teams, revenue teams are becoming more common.

    They include all go-to-market teams like sales, marketing, customer success and customer support. In B2B sales, long-term customer relationships can be incredibly valuable. As such, the focus shifts away from new customer acquisition alone.

    For example, you can also track and optimise your onboarding process. Marketing gets involved in post-sale efforts to boost loyalty. Sales reps follow up with customer success to get new sales angles and insights. Customer support insights drive future product development.

    Everyone works together to meet high-level company goals.

    The next section will explore how to set up an attribution system.

    How to find the right mix of B2B marketing attribution tools

    For most B2B marketing teams, the main struggle with attribution is not with the strategy but with creating a reliable system that gives them the data points they need to implement that strategy.

    We’ll outline one approach you can take to achieve this without a million-dollar budget or internal data science team.

    Use website analytics to track touchpoints

    The first thing you want to do is install a reliable website analytics solution on your website. 

    Once you’ve got your analytics in place, use campaign tracking parameters to track touchpoints from external campaigns like email newsletters, social media ads, review sites (like Capterra) and third-party partner campaigns.

    This way, you get a clear picture of which sources are driving traffic and conversions, helping you improve your marketing strategies.

    With analytics installed, you can track the referring sources of visits, engagement and conversion events. A robust solution like Matomo tracks everything from traffic sources, marketing attribution and visitor counts to behavioural analytics, like clicks, scrolling patterns and form interactions on your site.

    Marketing attribution will give you a cohesive view of which traffic sources and campaigns drive conversions and revenue over long periods. With Matomo’s marketing attribution feature, you can even use different marketing attribution models to compare results :

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

    For example, in a single report, you can compare the last interaction, first interaction and linear (three common marketing attribution models). 

    In total, Matomo has 6 available attribution models to choose from :

    1. First interaction
    2. Last interaction
    3. Last non-direct 
    4. Linear
    5. Position based
    6. Time decay 

    These additional attribution models are crucial for B2B sites. While other web analytics solutions often limit to last-click attribution, this model isn’t optimal for B2B with extended sales cycles.

    Try Matomo for Free

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

    No credit card required

    Use a CRM to integrate customer data from multiple sources

    Use your CRM software to integrate customer data from multiple sources. This will give you the ability to get meaningful B2B marketing insights. For example, you can get company-level insights so you can view conversion information by company, not just by person.

    Done effectively, you can close the loop back to analytics data by integrating data from multiple teams and platforms. 

    Implement self-reported attribution

    To further enhance the data, add qualifying questions in the lead signup process to create a hybrid attribution model. This is also known as self-reported attribution.

    Example of self-reported attribution

    Your web analytics platform won’t always be able to track the source of certain visits — for instance, “dark social” or peer-to-peer sharing, where links are shared privately and are not easily traceable by analytics tools.

    Doing self-reported attribution is crucial for getting a holistic image of your customer journey. 

    However, self-reported attribution isn’t foolproof ; users may click randomly or inaccurately recall where they first heard about you. So it’s essential to blend this data with your analytics to gain a more accurate understanding.

    Best practices for handling B2B prospect data in a privacy-sensitive world 

    Lastly, it’s important to respect your prospects’ privacy and comply with privacy regulations when conducting B2B marketing attribution.

    Privacy regulations and their enforcement are rapidly gaining momentum around the globe. Meta recently received a record GDPR fine of €1.2 billion for insufficient privacy measures when handling user data by the Irish Data Protection Agency.

    If you don’t want to risk major fines (or customers feeling betrayed), you shouldn’t follow in the same footsteps.

    Switch to a privacy-friendly web analytics

    Instead of using a controversial solution like Google Analytics, use a privacy-friendly web analytics solution like Matomo, Fathom or Plausible. 

    These alternatives not only ensure compliance with regulations like GDPR but also provide peace of mind amid the uncertain relationship between Google and GDPR. Google Analytics has faced bans in recent years, raising concerns about the future of the solution.

    While organisations governed by GDPR can currently use Google Analytics, there’s no guarantee of its continued availability.

    Make the switch to privacy-friendly web analytics to avoid potential fines and disruptive rulings that could force you to change platforms urgently. Such disruptions can be catastrophic for marketing teams heavily reliant on web analytics for tracking campaigns, business goals and marketing efforts.

    Improve your B2B marketing attribution with Matomo

    Matomo’s privacy-by-design architecture makes it the perfect analytics platform for the modern B2B marketer. Matomo enables you to meet even the strictest privacy regulations.

    At the same time, through campaign tracking URLs, marketing attribution, integrations and our API, you can track the results of various marketing channels and campaigns effectively. We help you understand the impact of each dollar of your marketing budget. 

    If you want a competitive edge over other B2B companies, try Matomo for free for 21 days. No credit card required.