Recherche avancée

Médias (91)

Autres articles (88)

  • Amélioration de la version de base

    13 septembre 2013

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

  • Menus personnalisés

    14 novembre 2010, par

    MediaSPIP utilise le plugin Menus pour gérer plusieurs menus configurables pour la navigation.
    Cela permet de laisser aux administrateurs de canaux la possibilité de configurer finement ces menus.
    Menus créés à l’initialisation du site
    Par défaut trois menus sont créés automatiquement à l’initialisation du site : Le menu principal ; Identifiant : barrenav ; Ce menu s’insère en général en haut de la page après le bloc d’entête, son identifiant le rend compatible avec les squelettes basés sur Zpip ; (...)

  • Publier sur MédiaSpip

    13 juin 2013

    Puis-je poster des contenus à partir d’une tablette Ipad ?
    Oui, si votre Médiaspip installé est à la version 0.2 ou supérieure. Contacter au besoin l’administrateur de votre MédiaSpip pour le savoir

Sur d’autres sites (7923)

  • Stream image from Android with FFMPEG

    9 février 2023, par xnok

    I'm currently receiving images from an external source as byte array and I would like to send it as raw video format via ffmpeg to a stream URL, where I have a RTSP server that receives RTSP streams (a similar unanswered question). However, I haven't worked with FFMPEG in Java, so i can't find an example on how to do it. I have a callback that copies the image bytes to a byte array as follows :

    


            public class MainActivity extends Activity {
            final String rtmp_url = "rtmp://192.168.0.12:1935/live/test";
            private int PREVIEW_WIDTH = 384;
            private int PREVIEW_HEIGHT = 292;
            private String TAG = "MainActivity";
            String ffmpeg = Loader.load(org.bytedeco.ffmpeg.ffmpeg.class);
            final String command[] = {ffmpeg,
                            "-y",  //Add "-re" for simulated readtime streaming.
                            "-f", "rawvideo",
                            "-vcodec", "rawvideo",
                            "-pix_fmt", "bgr24",
                            "-s", (Integer.toString(PREVIEW_WIDTH) + "x" + Integer.toString(PREVIEW_HEIGHT)),
                            "-r", "10",
                            "-i", "pipe:",
                            "-c:v", "libx264",
                            "-pix_fmt", "yuv420p",
                            "-preset", "ultrafast",
                            "-f", "flv",
                            rtmp_url};
            
      private UVCCamera mUVCCamera;

public void handleStartPreview(Object surface) throws InterruptedException, IOException {
    Log.e(TAG, "handleStartPreview:mUVCCamera" + mUVCCamera + " mIsPreviewing:");
    if ((mUVCCamera == null)) return;
    Log.e(TAG, "handleStartPreview2 ");
    try {
        mUVCCamera.setPreviewSize(mWidth, mHeight, 1, 26, 0, UVCCamera.DEFAULT_BANDWIDTH, 0);
        Log.e(TAG, "handleStartPreview3 mWidth: " + mWidth + "mHeight:" + mHeight);
    } catch (IllegalArgumentException e) {
        try {
            // fallback to YUV mode
            mUVCCamera.setPreviewSize(mWidth, mHeight, 1, 26, UVCCamera.DEFAULT_PREVIEW_MODE, UVCCamera.DEFAULT_BANDWIDTH, 0);
            Log.e(TAG, "handleStartPreview4");
        } catch (IllegalArgumentException e1) {
            callOnError(e1);
            return;
        }
    }
    Log.e(TAG, "handleStartPreview: startPreview1");
    int result = mUVCCamera.startPreview();
    mUVCCamera.setFrameCallback(mIFrameCallback, UVCCamera.PIXEL_FORMAT_RGBX);
    mUVCCamera.startCapture();
    Toast.makeText(MainActivity.this,"Camera Started",Toast.LENGTH_SHORT).show();
    ProcessBuilder pb = new ProcessBuilder(command);
    pb.redirectErrorStream(true);
    Process process = pb.start();
    BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
    OutputStream writer = process.getOutputStream();
    byte img[] = new byte[192*108*3];
    for (int i = 0; i < 10; i++)
    {
        for (int y = 0; y < 108; y++)
        {
            for (int x = 0; x < 192; x++)
            {
                byte r = (byte)((x * y + i) % 255);
                byte g = (byte)((x * y + i*10) % 255);
                byte b = (byte)((x * y + i*20) % 255);
                img[(y*192 + x)*3] = b;
                img[(y*192 + x)*3+1] = g;
                img[(y*192 + x)*3+2] = r;
            }
        }

        writer.write(img);
    }

    writer.close();
    String line;
    while ((line = reader.readLine()) != null)
    {
        System.out.println(line);
    }

    process.waitFor();
}
public static void buildRawFrame(Mat img, int i)
{
    int p = img.cols() / 60;
    img.setTo(new Scalar(60, 60, 60));
    String text = Integer.toString(i+1);
    int font = Imgproc.FONT_HERSHEY_SIMPLEX;
    Point pos = new Point(img.cols()/2-p*10*(text.length()), img.rows()/2+p*10);
    Imgproc.putText(img, text, pos, font, p, new Scalar(255, 30, 30), p*2);  //Blue number
}


    


    Additionally : Android Camera Capture using FFmpeg

    


    uses ffmpeg to capture frame by frame from native android camera and instead of pushing it via RTMP, they used to generate a video file as output. Although how the image was passed via ffmpeg was not informed.

    


    frameData is my byte array and I'd like to know how can I write the necessary ffmpeg commands using ProcessBuilder to send an image via RTSP using ffmpeg for a given URL.

    


    An example of what I am trying to do, In Python 3 I could easily do it by doing :

    


    import cv2
import numpy as np
import socket
import sys
import pickle
import struct
import subprocess

fps = 25
width = 224
height = 224
rtmp_url = 'rtmp://192.168.0.13:1935/live/test'
    
    
    
    command = ['ffmpeg',
               '-y',
               '-f', 'rawvideo',
               '-vcodec', 'rawvideo',
               '-pix_fmt', 'bgr24',
               '-s', "{}x{}".format(width, height),
               '-r', str(fps),
               '-i', '-',
               '-c:v', 'libx264',
               '-pix_fmt', 'yuv420p',
               '-preset', 'ultrafast',
               '-f', 'flv',
               rtmp_url]
    
    p = subprocess.Popen(command, stdin=subprocess.PIPE)
    
    while(True):
        frame = np.random.randint([255], size=(224, 224, 3))
        frame = frame.astype(np.uint8)
        p.stdin.write(frame.tobytes())


    


    I would like to do the same thing in Android

    


    Update : I can reproduce @Rotem 's answer on Netbeans although, in Android I am getting NullPointer exception error when trying to execute pb.start().

    


        Process: com.infiRay.XthermMini, PID: 32089
    java.lang.NullPointerException
        at java.lang.ProcessBuilder.start(ProcessBuilder.java:1012)
        at com.infiRay.XthermMini.MainActivity.handleStartPreview(MainActivity.java:512)
        at com.infiRay.XthermMini.MainActivity.startPreview(MainActivity.java:563)
        at com.infiRay.XthermMini.MainActivity.access$1000(MainActivity.java:49)
        at com.infiRay.XthermMini.MainActivity$3.onConnect(MainActivity.java:316)
        at com.serenegiant.usb.USBMonitor$3.run(USBMonitor.java:620)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loopOnce(Looper.java:226)
        at android.os.Looper.loop(Looper.java:313)
        at android.os.HandlerThread.run(HandlerThread.java:67)
2022-06-02 11:47:20.300 32089-1049/com.infiRay.XthermMini E/libUVCCamera: [1049*UVCPreviewIR.cpp:505:uvc_preview_frame_callback]:receive err data
2022-06-02 11:47:20.304 32089-1049/com.infiRay.XthermMini E/libUVCCamera: [1049*UVCPreviewIR.cpp:505:uvc_preview_frame_callback]:receive err data
2022-06-02 11:47:20.304 32089-1049/com.infiRay.XthermMini E/libUVCCamera: [1049*UVCPreviewIR.cpp:505:uvc_preview_frame_callback]:receive err data
2022-06-02 11:47:20.308 32089-1049/com.infiRay.XthermMini E/libUVCCamera: [1049*UVCPreviewIR.cpp:505:uvc_preview_frame_callback]:receive err data
2022-06-02 11:47:20.312 32089-32089/com.infiRay.XthermMini E/MainActivity: onPause:
2022-06-02 11:47:20.314 32089-32581/com.infiRay.XthermMini I/Process: Sending signal. PID: 32089 SIG: 9


    


  • ffmpeg Undefined referance to several swr functions [duplicate]

    21 mai 2022, par user19068953

    I'm trying to staticly link ffmpeg to my project, i downloaded the ffmpeg source files from a github repo because it had pre writen cmake files, which i needed for this exact problem but it changed nothing (https://github.com/Pawday/ffmpeg-cmake). I edited the file a little and posted it below, and added them to lib/ffmpeg in my project directory. I first ran ./configure, then ran make, then make install like the install guide suggested. Then i ran cmake . followed by make. It compiled just fine and i ran a test without any errors :

    


    extern "C"{&#xA;    #include <libavcodec></libavcodec>avcodec.h>&#xA;}&#xA;&#xA;#include <iostream>&#xA;int main(int argc, char* argv[]) {&#xA;    if (argc &lt; 2) {&#xA;        std::cout &lt;&lt; "provide a filename" &lt;&lt; std::endl;&#xA;        return -1;&#xA;        AVPacket *pkt = av_packet_alloc();&#xA;    }&#xA;}&#xA;</iostream>

    &#xA;

    I was following the examples that ffmpeg provides, so i added this :

    &#xA;

    const AVCodec *codec = avcodec_find_decoder(AV_CODEC_ID_MPEG1VIDEO);&#xA;

    &#xA;

    But now i have this huge error :

    &#xA;

    /usr/bin/ld: /usr/local/lib/libavcodec.a(opusdec.o): in function &#xA;&#xA;`opus_decode_subpacket&#x27;:&#xA;/home/t/Desktop/Code/lib/ffmpeg/libavcodec/opusdec.c:346: undefined reference to `swr_is_initialized&#x27;&#xA;/usr/bin/ld: /usr/local/lib/libavcodec.a(opusdec.o): in function `opus_decode_frame&#x27;:&#xA;/home/t/Desktop/Code/lib/ffmpeg/libavcodec/opusdec.c:188: undefined reference to `swr_is_initialized&#x27;&#xA;/usr/bin/ld: /usr/local/lib/libavcodec.a(opusdec.o): in function `opus_init_resample&#x27;:&#xA;/home/t/Desktop/Code/lib/ffmpeg/libavcodec/opusdec.c:136: undefined reference to `swr_init&#x27;&#xA;/usr/bin/ld: /home/t/Desktop/Code/lib/ffmpeg/libavcodec/opusdec.c:142: undefined reference to `swr_convert&#x27;&#xA;/usr/bin/ld: /usr/local/lib/libavcodec.a(opusdec.o): in function `opus_decode_frame&#x27;:&#xA;/home/t/Desktop/Code/lib/ffmpeg/libavcodec/opusdec.c:202: undefined reference to `swr_convert&#x27;&#xA;/usr/bin/ld: /usr/local/lib/libavcodec.a(opusdec.o): in function `opus_flush_resample&#x27;:&#xA;/home/t/Desktop/Code/lib/ffmpeg/libavcodec/opusdec.c:90: undefined reference to `swr_convert&#x27;&#xA;/usr/bin/ld: /usr/local/lib/libavcodec.a(opusdec.o): in function `opus_decode_subpacket&#x27;:&#xA;/home/t/Desktop/Code/lib/ffmpeg/libavcodec/opusdec.c:379: undefined reference to `swr_close&#x27;&#xA;/usr/bin/ld: /home/t/Desktop/Code/lib/ffmpeg/libavcodec/opusdec.c:346: undefined reference to `swr_is_initialized&#x27;&#xA;/usr/bin/ld: /usr/local/lib/libavcodec.a(opusdec.o): in function `opus_decode_flush&#x27;:&#xA;/home/t/Desktop/Code/lib/ffmpeg/libavcodec/opusdec.c:582: undefined reference to `swr_close&#x27;&#xA;/usr/bin/ld: /usr/local/lib/libavcodec.a(opusdec.o): in function `opus_decode_close&#x27;:&#xA;/home/t/Desktop/Code/lib/ffmpeg/libavcodec/opusdec.c:607: undefined reference to `swr_free&#x27;&#xA;/usr/bin/ld: /usr/local/lib/libavcodec.a(opusdec.o): in function `opus_decode_init&#x27;:&#xA;/home/t/Desktop/Code/lib/ffmpeg/libavcodec/opusdec.c:660: undefined reference to `swr_alloc&#x27;&#xA;collect2: error: ld returned 1 exit status&#xA;make[2]: *** [CMakeFiles/Interview.dir/build.make:122: bin/Interview] Error 1&#xA;make[1]: *** [CMakeFiles/Makefile2:420: CMakeFiles/Interview.dir/all] Error 2&#xA;make: *** [Makefile:84: all] Error 2&#xA;

    &#xA;

    I find some questions with similar issues to no avail :

    &#xA;

    FFmpeg seems to be version conflict&#xA;Linking libavcodec and libavformat : Undefined references

    &#xA;

    NOTE : previously i tried downloading ffmpeg with home-brew and pkg-config maybe that is causing an error, but my guess is my cmake file is faulty.

    &#xA;

    project/CMakeLists :

    &#xA;

    cmake_minimum_required(VERSION 3.14)&#xA;&#xA;project(Interview C CXX)&#xA;set(CMAKE_CXX_STANDARD 14)&#xA;&#xA;SET( EXECUTABLE_OUTPUT_PATH ${dir}/bin )&#xA;set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin )&#xA;set( CMAKE_C_FLAGS "-lswresample")&#xA;&#xA;add_subdirectory(lib/ffmpeg)&#xA;&#xA;add_definitions(-DGL_SILENCE_DEPRECATION)&#xA;&#xA;list(APPEND SOURCES&#xA;    src/main.cpp&#xA;    src/vipch.h&#xA;    src/VideoDecoder.cpp&#xA;    src/VideoDecoder.h&#xA;    src/Application.cpp&#xA;    src/Application.h&#xA;    #src/OpenGLRenderer.cpp&#xA;    #src/OpenGLRenderer.h&#xA;    #src/Layer.h&#xA;    #src/Layer.cpp&#xA;)&#xA;&#xA;find_path(AVCODEC_INCLUDE_DIR libavcodec/avcodec.h)&#xA;find_library(AVCODEC_LIBRARY avcodec)&#xA;&#xA;find_path(AVFORMAT_INCLUDE_DIR libavformat/avformat.h)&#xA;find_library(AVFORMAT_LIBRARY avformat)&#xA;&#xA;find_path(AVDEVICE_INCLUDE_DIR libavdevice/avdevice.h)&#xA;find_library(AVDEVICE_LIBRARY avdevice)&#xA;&#xA;find_path(AVCODEC_INCLUDE_DIR libavcodec/avcodec.h)&#xA;find_library(AVCODEC_LIBRARY avcodec)&#xA;&#xA;set(THREADS_PREFER_PTHREAD_FLAG ON)&#xA;find_package(Threads REQUIRED)&#xA;&#xA;add_executable(Interview src/main.cpp src/Application.cpp src/Application.h ${SOURCES})&#xA;&#xA;target_link_libraries(Interview PRIVATE Threads::Threads)&#xA;&#xA;if(APPLE)&#xA;    list(APPEND EXTRA_LIBS&#xA;        "-framework OpenGL"&#xA;    )&#xA;&#xA;    configure_file(&#xA;        ${CMAKE_CURRENT_SOURCE_DIR}/assets/MacOSXBundleInfo.plist.in&#xA;        ${CMAKE_CURRENT_BINARY_DIR}/assets/MacOSXBundleInfo.plist&#xA;    )&#xA;&#xA;    set_target_properties(Interview PROPERTIES&#xA;        MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_BINARY_DIR}/assets/MacOSXBundleInfo.plist&#xA;    )&#xA;&#xA;elseif(WIN32)&#xA;    list(APPEND EXTRA_LIBS&#xA;        "-lglu32 -lopengl32"&#xA;    )&#xA;    set(CMAKE_EXE_LINKER_FLAGS "-std=gnu99 -static -static-libgcc -static-libstdc&#x2B;&#x2B; -mwindows")&#xA;&#xA;endif()&#xA;&#xA;list(APPEND EXTRA_LIBS&#xA;"-lGL -lGLU -lX11 -lz -lva -lswresample"&#xA;)&#xA;&#xA;find_package(OpenGL REQUIRED)&#xA;find_package(GLEW REQUIRED)&#xA;&#xA;#target_link_libraries(Interview ${CORELIBS})&#xA;&#xA;&#xA;target_include_directories(Interview PRIVATE &#xA;    ${AVCODEC_INCLUDE_DIR} &#xA;    ${AVFORMAT_INCLUDE_DIR}&#xA;    ${AVUTIL_INCLUDE_DIR}&#xA;    ${AVDEVICE_INCLUDE_DIR} &#xA;    ${OPENGL_INCLUDE_DIR}&#xA;    ${GLEW_INCLUDE_DIRS}&#xA;)&#xA;&#xA;target_link_libraries(Interview PRIVATE &#xA;    ${AVCODEC_LIBRARY} &#xA;    ${AVFORMAT_LIBRARY} &#xA;    ${AVUTIL_LIBRARY} &#xA;    ${AVDEVICE_LIBRARY} &#xA;    ${OPENGL_LIBRARY}&#xA;    ${GLEW_LIBRARIES}&#xA;)&#xA;

    &#xA;

    NOTE : i previously had a really similar error with pthread but with some fixes to cmake and installing pthread i fixed it.

    &#xA;

    project/lib/ffmpeg/CMakeLists :

    &#xA;

    cmake_minimum_required(VERSION 3.15)&#xA;&#xA;project(FFMPEG C CXX)&#xA;&#xA;add_library(ffmpeg_config INTERFACE)&#xA;&#xA;#TODO:[cmake] COMMON DEFINES (config.h)&#xA;# create list with all that and then pick required from that list in each target&#xA;target_compile_definitions(ffmpeg_config INTERFACE FFMPEG_CONFIGURATION="")&#xA;target_compile_definitions(ffmpeg_config INTERFACE FFMPEG_DATADIR="")&#xA;target_compile_definitions(ffmpeg_config INTERFACE AVCONV_DATADIR="")&#xA;target_compile_definitions(ffmpeg_config INTERFACE FFMPEG_LICENSE="")&#xA;&#xA;target_compile_definitions(ffmpeg_config INTERFACE CC_IDENT="")&#xA;&#xA;target_compile_definitions(ffmpeg_config INTERFACE HAVE_THREADS=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE HAVE_PTHREADS=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE HAVE_W32THREADS=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE HAVE_OS2THREADS=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE HAVE_ISNAN=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE HAVE_MMXEXT=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE HAVE_MMX2=HAVE_MMXEXT)&#xA;target_compile_definitions(ffmpeg_config INTERFACE HAVE_MMX2=HAVE_MMXEXT)&#xA;target_compile_definitions(ffmpeg_config INTERFACE HAVE_MMX_INLINE=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE HAVE_MMX=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE HAVE_AV_CONFIG_H=1)&#xA;target_compile_definitions(ffmpeg_config INTERFACE HAVE_ALTIVEC=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE HAVE_MMXEXT_INLINE=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE HAVE_NEON=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE HAVE_AMD3DNOW_INLINE=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE HAVE_X86ASM=0)&#xA;if(WIN32)&#xA;    target_compile_definitions(ffmpeg_config INTERFACE HAVE_MKSTEMP=0)&#xA;else()&#xA;    target_compile_definitions(ffmpeg_config INTERFACE HAVE_MKSTEMP=1)&#xA;endif()&#xA;&#xA;&#xA;#TODO:[cmake] detect each function and set to 0 if missing (they are in math.h)&#xA;target_compile_definitions(ffmpeg_config INTERFACE HAVE_CBRT=1)&#xA;target_compile_definitions(ffmpeg_config INTERFACE HAVE_CBRTF=1)&#xA;target_compile_definitions(ffmpeg_config INTERFACE HAVE_COPYSIGN=1)&#xA;target_compile_definitions(ffmpeg_config INTERFACE HAVE_ERF=1)&#xA;target_compile_definitions(ffmpeg_config INTERFACE HAVE_HYPOT=1)&#xA;target_compile_definitions(ffmpeg_config INTERFACE HAVE_RINT=1)&#xA;target_compile_definitions(ffmpeg_config INTERFACE HAVE_LRINT=1)&#xA;target_compile_definitions(ffmpeg_config INTERFACE HAVE_LRINTF=1)&#xA;target_compile_definitions(ffmpeg_config INTERFACE HAVE_ROUND=1)&#xA;target_compile_definitions(ffmpeg_config INTERFACE HAVE_ROUNDF=1)&#xA;target_compile_definitions(ffmpeg_config INTERFACE HAVE_TRUNC=1)&#xA;target_compile_definitions(ffmpeg_config INTERFACE HAVE_TRUNCF=1)&#xA;&#xA;&#xA;target_link_libraries(ffmpeg_config INTERFACE ffmpeg_compat)&#xA;&#xA;include (TestBigEndian)&#xA;TEST_BIG_ENDIAN(IS_BIG_ENDIAN)&#xA;if(IS_BIG_ENDIAN)&#xA;    target_compile_definitions(ffmpeg_config INTERFACE HAVE_BIGENDIAN=1)&#xA;else()&#xA;    target_compile_definitions(ffmpeg_config INTERFACE HAVE_BIGENDIAN=0)&#xA;endif()&#xA;&#xA;target_compile_definitions(ffmpeg_config INTERFACE av_restrict=)&#xA;&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_THIS_YEAR=2021)&#xA;&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_MEMORY_POISONING=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_FRAME_THREAD_ENCODER=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_MEMORY_POISONING=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_GRAY=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_ERROR_RESILIENCE=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_MPEGVIDEODEC=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_SMALL=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_H264_D3D11VA_HWACCEL=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_H264_DXVA2_HWACCEL=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_H264_NVDEC_HWACCEL=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_H264_VAAPI_HWACCEL=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_H264_VIDEOTOOLBOX_HWACCEL=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_H264_VDPAU_HWACCEL=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_NETWORK=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_XVMC=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_FORMAT_FILTER=1)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_PNG_DECODER=1)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_APNG_DECODER=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_INFLATE_WRAPPER=1)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_DEFLATE_WRAPPER=1)&#xA;&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_AVUTIL=1)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_AVCODEC=1)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_AVFORMAT=1)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_AVDEVICE=1)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_SWSCALE=1)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_SWRESAMPLE=1)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_POSTPROC=1)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_AVFILTER=1)&#xA;&#xA;&#xA;&#xA;#CONFIG MUXERS&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_H264_MUXER=1)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_IMAGE2_MUXER=1)&#xA;&#xA;#CONFIG DEMUXERS&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_IMAGE2_DEMUXER=1)&#xA;&#xA;# look at the end of libavformat/img2dec.c file&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_IMAGE_BMP_PIPE_DEMUXER=1)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_IMAGE_CRI_PIPE_DEMUXER=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_IMAGE_DDS_PIPE_DEMUXER=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_IMAGE_DPX_PIPE_DEMUXER=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_IMAGE_EXR_PIPE_DEMUXER=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_IMAGE_GEM_PIPE_DEMUXER=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_IMAGE_GIF_PIPE_DEMUXER=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_IMAGE_J2K_PIPE_DEMUXER=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_IMAGE_JPEG_PIPE_DEMUXER=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_IMAGE_JPEGLS_PIPE_DEMUXER=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_IMAGE_PAM_PIPE_DEMUXER=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_IMAGE_PBM_PIPE_DEMUXER=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_IMAGE_PCX_PIPE_DEMUXER=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_IMAGE_PGM_PIPE_DEMUXER=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_IMAGE_PGMYUV_PIPE_DEMUXER=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_IMAGE_PGX_PIPE_DEMUXER=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_IMAGE_PHOTOCD_PIPE_DEMUXER=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_IMAGE_PICTOR_PIPE_DEMUXER=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_IMAGE_PNG_PIPE_DEMUXER=1)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_IMAGE_PPM_PIPE_DEMUXER=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_IMAGE_PSD_PIPE_DEMUXER=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_IMAGE_QDRAW_PIPE_DEMUXER=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_IMAGE_SGI_PIPE_DEMUXER=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_IMAGE_SUNRAST_PIPE_DEMUXER=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_IMAGE_SVG_PIPE_DEMUXER=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_IMAGE_TIFF_PIPE_DEMUXER=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_IMAGE_WEBP_PIPE_DEMUXER=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_IMAGE_XBM_PIPE_DEMUXER=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_IMAGE_XPM_PIPE_DEMUXER=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_IMAGE_XWD_PIPE_DEMUXER=0)&#xA;&#xA;&#xA;#CONFIG PROTOCOLS&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_FILE_PROTOCOL=1)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_PIPE_PROTOCOL=1)&#xA;&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_ZLIB=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE CONFIG_SWSCALE_ALPHA=0)&#xA;&#xA;target_compile_definitions(ffmpeg_config INTERFACE ARCH_X86_32=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE ARCH_X86_64=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE ARCH_AARCH64=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE ARCH_ARM=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE ARCH_PPC=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE ARCH_X86=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE ARCH_MIPS=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE ARCH_ALPHA=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE ARCH_LOONGARCH=0)&#xA;target_compile_definitions(ffmpeg_config INTERFACE ARCH_LOONGARCH64=0)&#xA;&#xA;target_compile_definitions(ffmpeg_config INTERFACE SWS_MAX_FILTER_SIZE=256)&#xA;&#xA;#_________________________WARNINGS__________________________________________&#xA;#TODO[cmake]: set it for all targets individually or remove for WARNING HELL&#xA;if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")&#xA;    add_compile_options("-w")&#xA;endif()&#xA;&#xA;if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")&#xA;    add_compile_options("-w")&#xA;endif()&#xA;&#xA;if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")&#xA;    cmake_policy(SET CMP0092 NEW) #cmake disable std MSVC warnings in CMAKE_C_FLAGS&#xA;    #CMAKE_DEPFILE_FLAGS_C var in windows contains only /showIncludes and produce include tree&#xA;    set(CMAKE_DEPFILE_FLAGS_C "") #erase it&#xA;    add_compile_options("/w")&#xA;endif()&#xA;&#xA;file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/include/config.h "//cmake config will define all that")&#xA;target_include_directories(ffmpeg_config INTERFACE ${CMAKE_CURRENT_BINARY_DIR}/include)&#xA;&#xA;#TODO[cmake]: resolve config_components.h&#xA;file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/include/config_components.h "//")&#xA;target_include_directories(ffmpeg_config INTERFACE ${CMAKE_CURRENT_BINARY_DIR}/include)&#xA;&#xA;add_subdirectory(compat)&#xA;add_subdirectory(libavutil)&#xA;add_subdirectory(libavcodec)&#xA;add_subdirectory(libavformat)&#xA;add_subdirectory(libavdevice)&#xA;add_subdirectory(libavfilter)&#xA;add_subdirectory(libswresample)&#xA;add_subdirectory(libswscale)&#xA;add_subdirectory(libpostproc)&#xA;&#xA;add_subdirectory(fftools)&#xA;&#xA;add_subdirectory(doc/examples)&#xA;&#xA;&#xA;find_path(AVCODEC_INCLUDE_DIR libavcodec/avcodec.h)&#xA;find_library(AVCODEC_LIBRARY avcodec)&#xA;&#xA;find_path(AVFORMAT_INCLUDE_DIR libavformat/avformat.h)&#xA;find_library(AVFORMAT_LIBRARY avformat)&#xA;&#xA;find_path(AVDEVICE_INCLUDE_DIR libavdevice/avdevice.h)&#xA;find_library(AVDEVICE_LIBRARY avdevice)&#xA;&#xA;find_path(AVCODEC_INCLUDE_DIR libavcodec/avcodec.h)&#xA;find_library(AVCODEC_LIBRARY avcodec)&#xA;&#xA;if(APPLE)&#xA;    list(APPEND EXTRA_LIBS&#xA;        "-framework OpenGL"&#xA;    )&#xA;&#xA;    configure_file(&#xA;        ${CMAKE_CURRENT_SOURCE_DIR}/assets/MacOSXBundleInfo.plist.in&#xA;        ${CMAKE_CURRENT_BINARY_DIR}/assets/MacOSXBundleInfo.plist&#xA;    )&#xA;&#xA;    set_target_properties(FFMPEG PROPERTIES&#xA;        MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_BINARY_DIR}/assets/MacOSXBundleInfo.plist&#xA;    )&#xA;&#xA;elseif(WIN32)&#xA;    list(APPEND EXTRA_LIBS&#xA;        "-lglu32 -lopengl32"&#xA;    )&#xA;    set(CMAKE_EXE_LINKER_FLAGS "-std=gnu99 -static -static-libgcc -static-libstdc&#x2B;&#x2B; -mwindows")&#xA;else()&#xA;    list(APPEND EXTRA_LIBS&#xA;        "-lGL -lGLU -lX11"&#xA;    )&#xA;endif()&#xA;&#xA;&#xA;#target_link_libraries(Interview ${CORELIBS})&#xA;&#xA;set( CMAKE_C_FLAGS "-lswresample")&#xA;&#xA;list(APPEND EXTRA_LIBS&#xA;"-lGL -lGLU -lX11 -lz -lva -lswresample"&#xA;)&#xA;&#xA;target_include_directories(ffmpeg_config INTERFACE&#xA;    ${AVCODEC_INCLUDE_DIR} &#xA;    ${AVFORMAT_INCLUDE_DIR}&#xA;    ${AVUTIL_INCLUDE_DIR}&#xA;    ${AVDEVICE_INCLUDE_DIR} &#xA;    ${OPENGL_INCLUDE_DIR}&#xA;    ${GLEW_INCLUDE_DIRS}&#xA;)&#xA;&#xA;target_link_libraries(ffmpeg_config INTERFACE&#xA;    ${AVCODEC_LIBRARY} &#xA;    ${AVFORMAT_LIBRARY} &#xA;    ${AVUTIL_LIBRARY} &#xA;    ${AVDEVICE_LIBRARY} &#xA;    ${OPENGL_LIBRARY}&#xA;    ${GLEW_LIBRARIES}&#xA;)&#xA;

    &#xA;

    Ubuntu 22.04, cmake 3.16.3, ffmpeg version git-2022-05-20-cb47f66

    &#xA;

  • 10 Key Google Analytics Limitations You Should Be Aware Of

    9 mai 2022, par Erin

    Google Analytics (GA) is the biggest player in the web analytics space. But is it as “universal” as its brand name suggests ?

    Over the years users have pointed out a number of major Google Analytics limitations. Many of these are even more visible in Google Analytics 4. 

    Introduced in 2020, Google Analytics 4 (GA4) has been sceptically received. As the sunset date of 1st, July 2023 for the current version, Google Universal Analytics (UA), approaches, the dismay grows stronger.

    To the point where people are pleading with others to intervene : 

    GA4 Elon Musk Tweet
    Source : Chris Tweten via Twitter

    Main limitations of Google Analytics

    Google Analytics 4 is advertised as a more privacy-centred, comprehensive and “intelligent” web analytics platform. 

    According to Google, the newest version touts : 

    • Machine learning at its core provides better segmentation and fast-track access to granular insights 
    • Privacy-by-design controls, addressing restrictions on cookies and new regulatory demands 
    • More complete understanding of customer journeys across channels and devices 

    Some of these claims hold true. Others crumble upon a deeper investigation. Newly advertised Google Analytics capabilities such as ‘custom events’, ‘predictive insights’ and ‘privacy consent mode’ only have marginal improvements. 

    Complex setup, poor UI and lack of support with migration also leave many other users frustrated with GA4. 

    Let’s unpack all the current (and legacy) limitations of Google Analytics you should account for. 

    1. No Historical Data Imports 

    Google rushed users to migrate from Universal Analytics to Google Analytics 4. But they overlooked one important precondition — backwards compatibility. 

    You have no way to import data from Google Universal Analytics to Google Analytics 4. 

    Historical records are essential for analysing growth trends and creating benchmarks for new marketing campaigns. Effectively, you are cut short from past insights — and forced to start strategising from scratch. 

    At present, Google offers two feeble solutions : 

    • Run data collection in parallel and have separate reporting for GA4 and UA until the latter is shut down. Then your UA records are gone. 
    • For Ecommerce data, manually duplicate events from UA at a new GA4 property while trying to figure out the new event names and parameters. 

    Google’s new data collection model is the reason for migration difficulties. 

    In Google Analytics 4, all analytics hits types — page hits, social hits, app/screen view, etc. — are recorded as events. Respectively, the “‘event’ parameter in GA4 is different from one in Google Universal Analytics as the company explains : 

    GA4 vs Universal Analytics event parameters
    Source : Google

    This change makes migration tedious — and Google offers little assistance with proper events and custom dimensions set up. 

    2. Data Collection Limits 

    If you’ve wrapped your head around new GA4 events, congrats ! You did a great job, but the hassle isn’t over. 

    You still need to pay attention to new Google Analytics limits on data collection for event parameters and user properties. 

    GA4 Event limits
    Source : Google

    These apply to :

    • Automatically collected events
    • Enhanced measurement events
    • Recommended events 
    • Custom events 

    When it comes to custom events, GA4 also has a limit of 25 custom parameters per event. Even though it seems a lot, it may not be enough for bigger websites. 

    You can get higher limits by upgrading to Google Analytics 360, but the costs are steep. 

    3. Limited GDPR Compliance 

    Google Analytics has a complex history with European GDPR compliance

    A 2020 ruling by the Court of Justice of the European Union (CJEU) invalidated the Privacy Shield framework Google leaned upon. This framework allowed the company to regulate EU-US data transfers of sensitive user data. 

    But after this loophole was closed, Google faced a heavy series of privacy-related fines :

    • French data protection authority, CNIL, ruled that  “the transfers to the US of personal data collected through Google Analytics are illegal” — and proceeded to fine Google for a record-setting €150 million at the beginning of 2022. 
    • Austrian regulators also deemed Google in breach of GDPR requirements and also branded the analytics as illegal. 

    Other EU-member states might soon proceed with similar rulings. These, in turn, can directly affect Google Analytics users, whose businesses could face brand damage and regulatory fines for non-compliance. In fact, companies cannot select where the collected analytics data will be stored — on European servers or abroad — nor can they obtain this information from Google.

    Getting a web analytics platform that allows you to keep data on your own servers or select specific Cloud locations is a great alternative. 

    Google also has been lax with its cookie consent policy and doesn’t properly inform consumers about data collection, storage or subsequent usage. Google Analytics 4 addresses this issue to an extent. 

    By default, GA4 relies on first-party cookies, instead of third-party ones — which is a step forward. But the user privacy controls are hard to configure without losing most of the GA4 functionality. Implementing user consent mode to different types of data collection also requires a heavy setup. 

    4. Strong Reliance on Sampled Data 

    To compensate for ditching third-party cookies, GA4 more heavily leans on sampled data and machine learning to fill the gaps in reporting. 

    In GA4 sampling automatically applies when you :

    • Perform advanced analysis such as cohort analysis, exploration, segment overlap or funnel analysis with not enough data 
    • Have over 10,000,000 data rows and generate any type of non-default report 

    Google also notes that data sampling can occur at lower thresholds when you are trying to get granular insights. If there’s not enough data or because Google thinks it’s too complex to retrieve. 

    In their words :

    Source : Google

    Data sampling adds “guesswork” to your reports, meaning you can’t be 100% sure of data accuracy. The divergence from actual data depends on the size and quality of sampled data. Again, this isn’t something you can control. 

    Unlike Google Analytics 4, Matomo applies no data sampling. Your reports are always accurate and fully representative of actual user behaviours. 

    5. No Proper Data Anonymization 

    Data anonymization allows you to collect basic analytics about users — visits, clicks, page views — but without personally identifiable information (or PII) such as geo-location, assigns tracking ID or other cookie-based data. 

    This reduced your ability to :

    • Remarket 
    • Identify repeating visitors
    • Do advanced conversion attribution 

    But you still get basic data from users who ignored or declined consent to data collection. 

    By default, Google Analytics 4 anonymizes all user IP addresses — an upgrade from UA. However, it still assigned a unique user ID to each user. These count as personal data under GDPR. 

    For comparison, Matomo provides more advanced privacy controls. You can anonymize :

    • Previously tracked raw data 
    • Visitor IP addresses
    • Geo-location information
    • User IDs 

    This can ensure compliance, especially if you operate in a sensitive industry — and delight privacy-mindful users ! 

    6. No Roll-Up Reporting

    Getting a bird’s-eye view of all your data is helpful when you need hotkey access to main sites — global traffic volume, user count or percentage of returning visitors.

    With Roll-Up Reporting, you can see global-performance metrics for multiple localised properties (.co.nz, .co.uk, .com, etc,) in one screen. Then zoom in on specific localised sites when you need to. 

    7. Report Processing Latency 

    The average data processing latency is 24-48 hours with Google Analytics. 

    Accounts with over 200,000 daily sessions get data refreshes only once a day. So you won’t be seeing the latest data on core metrics. This can be a bummer during one-day promo events like Black Friday or Cyber Monday when real-time information can prove to be game-changing ! 

    Matomo processes data with lower latency even for high-traffic websites. Currently, we have 6-24 hour latency for cloud deployments. On-premises web analytics can be refreshed even faster — within an hour or instantly, depending on the traffic volumes. 

    8. No Native Conversion Optimisation Features

    Google Analytics users have to use third-party tools to get deeper insights like how people are interacting with your webpage or call-to-action.

    You can use the free Google Optimize tool, but it comes with limits : 

    • No segmentation is available 
    • Only 10 simultaneous running experiments allowed 

    There isn’t a native integration between Google Optimize and Google Analytics 4. Instead, you have to manually link an Optimize Container to an analytics account. Also, you can’t select experiment dimensions in Google Analytics reports.

    What’s more, Google Optimize is a basic CRO tool, best suited for split testing (A/B testing) of copy, visuals, URLs and page layouts. If you want to get more advanced data, you need to pay for extra tools. 

    Matomo comes with a native set of built-in conversion optimization features : 

    • Heatmaps 
    • User session recording 
    • Sales funnel analysis 
    • A/B testing 
    • Form submission analytics 
    A/B test hypothesis testing on Matomo
    A/B test hypothesis testing on Matomo

    9. Deprecated Annotations

    Annotations come in handy when you need to provide extra context to other team members. For example, point out unusual traffic spikes or highlight a leak in the sales funnel. 

    This feature was available in Universal Analytics but is now gone in Google Analytics 4. But you can still quickly capture, comment and share knowledge with your team in Matomo. 

    You can add annotations to any graph that shows statistics over time including visitor reports, funnel analysis charts or running A/B tests. 

    10. No White Label Option 

    This might be a minor limitation of Google Analytics, but a tangible one for agency owners. 

    Offering an on-brand, embedded web analytics platform can elevate your customer experience. But white label analytics were never a thing with Google Analytics, unlike Matomo. 

    Wrap Up 

    Google set a high bar for web analytics. But Google Analytics inherent limitations around privacy, reporting and deployment options prompt more users to consider Google Analytics alternatives, like Matomo. 

    With Matomo, you can easily migrate your historical data records and store customer data locally or in a designated cloud location. We operate by a 100% unsampled data principle and provide an array of privacy controls for advanced compliance. 

    Start your 21-day free trial (no credit card required) to see how Matomo compares to Google Analytics !