Recherche avancée

Médias (1)

Mot : - Tags -/berlin

Autres articles (111)

  • 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

  • Support audio et vidéo HTML5

    10 avril 2011

    MediaSPIP utilise les balises HTML5 video et audio pour la lecture de documents multimedia en profitant des dernières innovations du W3C supportées par les navigateurs modernes.
    Pour les navigateurs plus anciens, le lecteur flash Flowplayer est utilisé.
    Le lecteur HTML5 utilisé a été spécifiquement créé pour MediaSPIP : il est complètement modifiable graphiquement pour correspondre à un thème choisi.
    Ces technologies permettent de distribuer vidéo et son à la fois sur des ordinateurs conventionnels (...)

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

Sur d’autres sites (10021)

  • Failing to build ffmpeg for Android

    3 octobre 2018, par Hamed Momeni

    I’m trying build the ffmpeg sources for Android using two different approaches :

    1. https://yesimroy.gitbooks.io/android-note/content/compile_ffmpeg_for_android.html
    2. https://github.com/Khang-NT/ffmpeg-binary-android

    The problem here is that I am facing a somewhat similar problem in both the approaches so I guess the problem lies not with those scripts but there is some thing off in my environment. Here are the outputs of both build scripts :

    For approach #1 :

    /home/hamed/dev/android-tools/android-sdk-linux/ndk-bundle/toolchains/x86-4.9/prebuilt/linux-x86_64/bin/i686-linux-android-gcc is unable to create an executable file.
    C compiler test failed.

    If you think configure made a mistake, make sure you are using the latest
    version from Git.  If the latest version fails, report the problem to the
    ffmpeg-user@ffmpeg.org mailing list or IRC #ffmpeg on irc.freenode.net.
    Include the log file "conflog.txt" produced by configure as this will help
    solve the problem.
    Makefile:2: ffbuild/config.mak: No such file or directory
    Makefile:40: /tools/Makefile: No such file or directory
    Makefile:41: /ffbuild/common.mak: No such file or directory
    Makefile:90: /libavutil/Makefile: No such file or directory
    Makefile:90: /ffbuild/library.mak: No such file or directory
    Makefile:92: /fftools/Makefile: No such file or directory
    Makefile:93: /doc/Makefile: No such file or directory
    Makefile:94: /doc/examples/Makefile: No such file or directory
    Makefile:159: /tests/Makefile: No such file or directory
    make: *** No rule to make target '/tests/Makefile'.  Stop.
    Makefile:2: ffbuild/config.mak: No such file or directory
    Makefile:40: /tools/Makefile: No such file or directory
    Makefile:41: /ffbuild/common.mak: No such file or directory
    Makefile:90: /libavutil/Makefile: No such file or directory
    Makefile:90: /ffbuild/library.mak: No such file or directory
    Makefile:92: /fftools/Makefile: No such file or directory
    Makefile:93: /doc/Makefile: No such file or directory
    Makefile:94: /doc/examples/Makefile: No such file or directory
    Makefile:159: /tests/Makefile: No such file or directory
    make: *** No rule to make target '/tests/Makefile'.  Stop.
    Makefile:2: ffbuild/config.mak: No such file or directory
    Makefile:40: /tools/Makefile: No such file or directory
    Makefile:41: /ffbuild/common.mak: No such file or directory
    Makefile:90: /libavutil/Makefile: No such file or directory
    Makefile:90: /ffbuild/library.mak: No such file or directory
    Makefile:92: /fftools/Makefile: No such file or directory
    Makefile:93: /doc/Makefile: No such file or directory
    Makefile:94: /doc/examples/Makefile: No such file or directory
    Makefile:159: /tests/Makefile: No such file or directory
    make: *** No rule to make target '/tests/Makefile'.  Stop.
    Android X86 builds finished

    And for approach #2 :

    checking how to print strings... printf
    checking for style of include used by make... GNU
    checking for arm-linux-androideabi-gcc... /home/hamed/dev/android-tools/android-ndk-r18/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc
    checking whether the C compiler works... no
    configure: error: in `/home/hamed/dev/projects/ffmpeg/ffmpeg-binary-android/build_scripts/opus-1.1.5':
    configure: error: C compiler cannot create executables

    I even tried redownloading the NDK fearing that the gcc compiler was corrupt but still the same error line appears.

    And this is the config.log file from the OPUS module of the second approach :

    This file contains any messages produced by compilers while
    running configure, to aid debugging if configure makes a mistake.

    It was created by opus configure 1.1.5, which was
    generated by GNU Autoconf 2.69.  Invocation command line was

     $ ./configure -v --prefix=/home/hamed/dev/projects/ffmpeg/ffmpeg-binary-android/build_scripts/build_dir --host=arm-linux-androideabi --enable-static --disable-shared --disable-doc --disable-extra-programs

    ## --------- ##
    ## Platform. ##
    ## --------- ##

    hostname = putech-laptop
    uname -m = x86_64
    uname -r = 4.15.0-36-generic
    uname -s = Linux
    uname -v = #39-Ubuntu SMP Mon Sep 24 16:19:09 UTC 2018

    /usr/bin/uname -p = unknown
    /bin/uname -X     = unknown

    /bin/arch              = unknown
    /usr/bin/arch -k       = unknown
    /usr/convex/getsysinfo = unknown
    /usr/bin/hostinfo      = unknown
    /bin/machine           = unknown
    /usr/bin/oslevel       = unknown
    /bin/universe          = unknown

    PATH: /home/hamed/.local/bin
    PATH: /home/hamed/.local/bin
    PATH: /usr/local/sbin
    PATH: /usr/local/bin
    PATH: /usr/sbin
    PATH: /usr/bin
    PATH: /sbin
    PATH: /bin
    PATH: /usr/games
    PATH: /usr/local/games
    PATH: /snap/bin
    PATH: /home/hamed/dev/go/bin
    PATH: /home/hamed/dev/android-tools/android-sdk-linux/platform-tools/
    PATH: /home/hamed/dev/go/bin
    PATH: /home/hamed/dev/android-tools/android-sdk-linux/platform-tools/
    PATH: /home/hamed/dev/projects/ffmpeg/ffmpeg-binary-android/build_scripts/build_dir/bin/


    ## ----------- ##
    ## Core tests. ##
    ## ----------- ##

    configure:2354: checking whether make supports nested variables
    configure:2371: result: yes
    configure:2437: checking for a BSD-compatible install
    configure:2505: result: /usr/bin/install -c
    configure:2516: checking whether build environment is sane
    configure:2571: result: yes
    configure:2630: checking for arm-linux-androideabi-strip
    configure:2657: result: /home/hamed/dev/android-tools/android-ndk-r18/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-strip
    configure:2722: checking for a thread-safe mkdir -p
    configure:2761: result: /bin/mkdir -p
    configure:2768: checking for gawk
    configure:2798: result: no
    configure:2768: checking for mawk
    configure:2784: found /usr/bin/mawk
    configure:2795: result: mawk
    configure:2806: checking whether make sets $(MAKE)
    configure:2828: result: yes
    configure:2953: checking whether to enable maintainer-specific portions of Makefiles
    configure:2962: result: yes
    configure:2980: checking build system type
    configure:2994: result: x86_64-unknown-linux-gnu
    configure:3014: checking host system type
    configure:3027: result: arm-unknown-linux-androideabi
    configure:3099: checking how to print strings
    configure:3126: result: printf
    configure:3159: checking for style of include used by make
    configure:3187: result: GNU
    configure:3218: checking for arm-linux-androideabi-gcc
    configure:3245: result: /home/hamed/dev/android-tools/android-ndk-r18/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc
    configure:3514: checking for C compiler version
    configure:3523: /home/hamed/dev/android-tools/android-ndk-r18/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc --version >&5
    Android (4751641 based on r328903) clang version 7.0.2 (https://android.googlesource.com/toolchain/clang 003100370607242ddd5815e4a043907ea9004281) (https://android.googlesource.com/toolchain/llvm 1d739ffb0366421d383e04ff80ec2ee591315116) (based on LLVM 7.0.2svn)
    Target: arm--linux-android
    Thread model: posix
    InstalledDir: /home/hamed/dev/android-tools/android-ndk-r18/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../../../../llvm/prebuilt/linux-x86_64/bin
    configure:3534: $? = 0
    configure:3523: /home/hamed/dev/android-tools/android-ndk-r18/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc -v >&5
    Android (4751641 based on r328903) clang version 7.0.2 (https://android.googlesource.com/toolchain/clang 003100370607242ddd5815e4a043907ea9004281) (https://android.googlesource.com/toolchain/llvm 1d739ffb0366421d383e04ff80ec2ee591315116) (based on LLVM 7.0.2svn)
    Target: arm--linux-android
    Thread model: posix
    InstalledDir: /home/hamed/dev/android-tools/android-ndk-r18/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../../../../llvm/prebuilt/linux-x86_64/bin
    configure:3534: $? = 0
    configure:3523: /home/hamed/dev/android-tools/android-ndk-r18/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc -V >&5
    clang: error: argument to '-V' is missing (expected 1 value)
    clang: error: no input files
    configure:3534: $? = 1
    configure:3523: /home/hamed/dev/android-tools/android-ndk-r18/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc -qversion >&5
    clang: error: unknown argument '-qversion', did you mean '--version'?
    clang: error: no input files
    configure:3534: $? = 1
    configure:3554: checking whether the C compiler works
    configure:3576: /home/hamed/dev/android-tools/android-ndk-r18/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc -mfloat-abi=softfp -marm -march=armv7-a -Os -O3   -I/home/hamed/dev/projects/ffmpeg/ffmpeg-binary-android/build_scripts/build_dir/include --sysroot=/home/hamed/dev/android-tools/android-ndk-r18/platforms/android-16/arch-arm/ -fPIE  --sysroot=/home/hamed/dev/android-tools/android-ndk-r18/platforms/android-16/arch-arm/  -L/home/hamed/dev/projects/ffmpeg/ffmpeg-binary-android/build_scripts/build_dir/lib -fPIE -pie  conftest.c  >&5
    /usr/bin/ld: unrecognised emulation mode: armelf_linux_eabi
    Supported emulations: elf_x86_64 elf32_x86_64 elf_i386 elf_iamcu i386linux elf_l1om elf_k1om i386pep i386pe
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    configure:3580: $? = 1
    configure:3618: result: no
    configure: failed program was:
    | /* confdefs.h */
    | #define PACKAGE_NAME "opus"
    | #define PACKAGE_TARNAME "opus"
    | #define PACKAGE_VERSION "1.1.5"
    | #define PACKAGE_STRING "opus 1.1.5"
    | #define PACKAGE_BUGREPORT "opus@xiph.org"
    | #define PACKAGE_URL ""
    | /* end confdefs.h.  */
    |
    | int
    | main ()
    | {
    |
    |   ;
    |   return 0;
    | }
    configure:3623: error: in `/home/hamed/dev/projects/ffmpeg/ffmpeg-binary-android/build_scripts/opus-1.1.5':
    configure:3625: error: C compiler cannot create executables
    See `config.log' for more details

    ## ---------------- ##
    ## Cache variables. ##
    ## ---------------- ##

    ac_cv_build=x86_64-unknown-linux-gnu
    ac_cv_env_ARM_NEON_INTR_CFLAGS_set=
    ac_cv_env_ARM_NEON_INTR_CFLAGS_value=
    ac_cv_env_CCASFLAGS_set=
    ac_cv_env_CCASFLAGS_value=
    ac_cv_env_CCAS_set=
    ac_cv_env_CCAS_value=
    ac_cv_env_CC_set=set
    ac_cv_env_CC_value=/home/hamed/dev/android-tools/android-ndk-r18/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc
    ac_cv_env_CFLAGS_set=set
    ac_cv_env_CFLAGS_value='-mfloat-abi=softfp -marm -march=armv7-a -Os -O3   -I/home/hamed/dev/projects/ffmpeg/ffmpeg-binary-android/build_scripts/build_dir/include --sysroot=/home/hamed/dev/android-tools/android-ndk-r18/platforms/android-16/arch-arm/ -fPIE '
    ac_cv_env_CPPFLAGS_set=set
    ac_cv_env_CPPFLAGS_value='--sysroot=/home/hamed/dev/android-tools/android-ndk-r18/platforms/android-16/arch-arm/ '
    ac_cv_env_CPP_set=set
    ac_cv_env_CPP_value=/home/hamed/dev/android-tools/android-ndk-r18/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-cpp
    ac_cv_env_LDFLAGS_set=set
    ac_cv_env_LDFLAGS_value='-L/home/hamed/dev/projects/ffmpeg/ffmpeg-binary-android/build_scripts/build_dir/lib -fPIE -pie '
    ac_cv_env_LIBS_set=
    ac_cv_env_LIBS_value=
    ac_cv_env_LT_SYS_LIBRARY_PATH_set=
    ac_cv_env_LT_SYS_LIBRARY_PATH_value=
    ac_cv_env_X86_AVX_CFLAGS_set=
    ac_cv_env_X86_AVX_CFLAGS_value=
    ac_cv_env_X86_SSE2_CFLAGS_set=
    ac_cv_env_X86_SSE2_CFLAGS_value=
    ac_cv_env_X86_SSE4_1_CFLAGS_set=
    ac_cv_env_X86_SSE4_1_CFLAGS_value=
    ac_cv_env_X86_SSE_CFLAGS_set=
    ac_cv_env_X86_SSE_CFLAGS_value=
    ac_cv_env_build_alias_set=
    ac_cv_env_build_alias_value=
    ac_cv_env_host_alias_set=set
    ac_cv_env_host_alias_value=arm-linux-androideabi
    ac_cv_env_target_alias_set=
    ac_cv_env_target_alias_value=
    ac_cv_host=arm-unknown-linux-androideabi
    ac_cv_path_install='/usr/bin/install -c'
    ac_cv_path_mkdir=/bin/mkdir
    ac_cv_prog_AWK=mawk
    ac_cv_prog_CC=/home/hamed/dev/android-tools/android-ndk-r18/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc
    ac_cv_prog_STRIP=/home/hamed/dev/android-tools/android-ndk-r18/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-strip
    ac_cv_prog_make_make_set=yes
    am_cv_make_support_nested_variables=yes

    ## ----------------- ##
    ## Output variables. ##
    ## ----------------- ##

    ACLOCAL='${SHELL} /home/hamed/dev/projects/ffmpeg/ffmpeg-binary-android/build_scripts/opus-1.1.5/missing aclocal-1.15'
    AMDEPBACKSLASH='\'
    AMDEP_FALSE='#'
    AMDEP_TRUE=''
    AMTAR='$${TAR-tar}'
    AM_BACKSLASH='\'
    AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
    AM_DEFAULT_VERBOSITY='0'
    AM_V='$(V)'
    AR='/home/hamed/dev/android-tools/android-ndk-r18/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ar'
    ARM2GNU_PARAMS=''
    ARM_NEON_INTR_CFLAGS=''
    AUTOCONF='${SHELL} /home/hamed/dev/projects/ffmpeg/ffmpeg-binary-android/build_scripts/opus-1.1.5/missing autoconf'
    AUTOHEADER='${SHELL} /home/hamed/dev/projects/ffmpeg/ffmpeg-binary-android/build_scripts/opus-1.1.5/missing autoheader'
    AUTOMAKE='${SHELL} /home/hamed/dev/projects/ffmpeg/ffmpeg-binary-android/build_scripts/opus-1.1.5/missing automake-1.15'
    AWK='mawk'
    CC='/home/hamed/dev/android-tools/android-ndk-r18/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc'
    CCAS=''
    CCASDEPMODE=''
    CCASFLAGS=''
    CCDEPMODE=''
    CFLAGS='-mfloat-abi=softfp -marm -march=armv7-a -Os -O3   -I/home/hamed/dev/projects/ffmpeg/ffmpeg-binary-android/build_scripts/build_dir/include --sysroot=/home/hamed/dev/android-tools/android-ndk-r18/platforms/android-16/arch-arm/ -fPIE '
    CPP='/home/hamed/dev/android-tools/android-ndk-r18/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-cpp'
    CPPFLAGS='--sysroot=/home/hamed/dev/android-tools/android-ndk-r18/platforms/android-16/arch-arm/ '
    CPU_ARM_FALSE=''
    CPU_ARM_TRUE=''
    CUSTOM_MODES_FALSE=''
    CUSTOM_MODES_TRUE=''
    CYGPATH_W='echo'
    DEFS=''
    DEPDIR='.deps'
    DISABLE_FLOAT_API_FALSE=''
    DISABLE_FLOAT_API_TRUE=''
    DLLTOOL=''
    DSYMUTIL=''
    DUMPBIN=''
    ECHO_C=''
    ECHO_N='-n'
    ECHO_T=''
    EGREP=''
    EXEEXT=''
    EXTRA_PROGRAMS_FALSE=''
    EXTRA_PROGRAMS_TRUE=''
    FGREP=''
    FIXED_POINT_FALSE=''
    FIXED_POINT_TRUE=''
    GREP=''
    HAVE_ARM_NE10=''
    HAVE_ARM_NE10_FALSE=''
    HAVE_ARM_NE10_TRUE=''
    HAVE_ARM_NEON_INTR_FALSE=''
    HAVE_ARM_NEON_INTR_TRUE=''
    HAVE_AVX_FALSE=''
    HAVE_AVX_TRUE=''
    HAVE_DOXYGEN=''
    HAVE_DOXYGEN_FALSE=''
    HAVE_DOXYGEN_TRUE=''
    HAVE_PERL=''
    HAVE_SSE2_FALSE=''
    HAVE_SSE2_TRUE=''
    HAVE_SSE4_1_FALSE=''
    HAVE_SSE4_1_TRUE=''
    HAVE_SSE_FALSE=''
    HAVE_SSE_TRUE=''
    INSTALL_DATA='${INSTALL} -m 644'
    INSTALL_PROGRAM='${INSTALL}'
    INSTALL_SCRIPT='${INSTALL}'
    INSTALL_STRIP_PROGRAM='$(install_sh) -c -s'
    LD='/home/hamed/dev/android-tools/android-ndk-r18/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ld'
    LDFLAGS='-L/home/hamed/dev/projects/ffmpeg/ffmpeg-binary-android/build_scripts/build_dir/lib -fPIE -pie '
    LIBM=''
    LIBOBJS=''
    LIBS=''
    LIBTOOL=''
    LIPO=''
    LN_S=''
    LTLIBOBJS=''
    LT_SYS_LIBRARY_PATH=''
    MAINT=''
    MAINTAINER_MODE_FALSE='#'
    MAINTAINER_MODE_TRUE=''
    MAKEINFO='${SHELL} /home/hamed/dev/projects/ffmpeg/ffmpeg-binary-android/build_scripts/opus-1.1.5/missing makeinfo'
    MANIFEST_TOOL=''
    MKDIR_P='/bin/mkdir -p'
    NE10_CFLAGS=''
    NE10_LIBS=''
    NM='/home/hamed/dev/android-tools/android-ndk-r18/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-nm'
    NMEDIT=''
    OBJDUMP=''
    OBJEXT=''
    OPUS_ARM_EXTERNAL_ASM_FALSE=''
    OPUS_ARM_EXTERNAL_ASM_TRUE=''
    OPUS_ARM_INLINE_ASM_FALSE=''
    OPUS_ARM_INLINE_ASM_TRUE=''
    OPUS_ARM_MAY_HAVE_EDSP=''
    OPUS_ARM_MAY_HAVE_MEDIA=''
    OPUS_ARM_MAY_HAVE_NEON=''
    OPUS_ARM_NEON_INTR_CFLAGS=''
    OPUS_HAVE_RTCD=''
    OPUS_LT_AGE='5'
    OPUS_LT_CURRENT='5'
    OPUS_LT_REVISION='5'
    OPUS_X86_AVX_CFLAGS=''
    OPUS_X86_SSE2_CFLAGS=''
    OPUS_X86_SSE4_1_CFLAGS=''
    OPUS_X86_SSE_CFLAGS=''
    OTOOL64=''
    OTOOL=''
    PACKAGE='opus'
    PACKAGE_BUGREPORT='opus@xiph.org'
    PACKAGE_NAME='opus'
    PACKAGE_STRING='opus 1.1.5'
    PACKAGE_TARNAME='opus'
    PACKAGE_URL=''
    PACKAGE_VERSION='1.1.5'
    PATH_SEPARATOR=':'
    PC_BUILD=''
    RANLIB='/home/hamed/dev/android-tools/android-ndk-r18/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ranlib'
    SED=''
    SET_MAKE=''
    SHELL='/bin/bash'
    STRIP='/home/hamed/dev/android-tools/android-ndk-r18/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-strip'
    VERSION='1.1.5'
    X86_AVX_CFLAGS=''
    X86_SSE2_CFLAGS=''
    X86_SSE4_1_CFLAGS=''
    X86_SSE_CFLAGS=''
    ac_ct_AR=''
    ac_ct_CC=''
    ac_ct_DUMPBIN=''
    am__EXEEXT_FALSE=''
    am__EXEEXT_TRUE=''
    am__fastdepCCAS_FALSE=''
    am__fastdepCCAS_TRUE=''
    am__fastdepCC_FALSE=''
    am__fastdepCC_TRUE=''
    am__include='include'
    am__isrc=''
    am__leading_dot='.'
    am__nodep='_no'
    am__quote=''
    am__tar='$${TAR-tar} chof - "$$tardir"'
    am__untar='$${TAR-tar} xf -'
    bindir='${exec_prefix}/bin'
    build='x86_64-unknown-linux-gnu'
    build_alias=''
    build_cpu='x86_64'
    build_os='linux-gnu'
    build_vendor='unknown'
    datadir='${datarootdir}'
    datarootdir='${prefix}/share'
    docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
    dvidir='${docdir}'
    exec_prefix='NONE'
    host='arm-unknown-linux-androideabi'
    host_alias='arm-linux-androideabi'
    host_cpu='arm'
    host_os='linux-androideabi'
    host_vendor='unknown'
    htmldir='${docdir}'
    includedir='${prefix}/include'
    infodir='${datarootdir}/info'
    install_sh='${SHELL} /home/hamed/dev/projects/ffmpeg/ffmpeg-binary-android/build_scripts/opus-1.1.5/install-sh'
    libdir='${exec_prefix}/lib'
    libexecdir='${exec_prefix}/libexec'
    localedir='${datarootdir}/locale'
    localstatedir='${prefix}/var'
    mandir='${datarootdir}/man'
    mkdir_p='$(MKDIR_P)'
    oldincludedir='/usr/include'
    pdfdir='${docdir}'
    prefix='/home/hamed/dev/projects/ffmpeg/ffmpeg-binary-android/build_scripts/build_dir'
    program_transform_name='s,x,x,'
    psdir='${docdir}'
    sbindir='${exec_prefix}/sbin'
    sharedstatedir='${prefix}/com'
    sysconfdir='${prefix}/etc'
    target_alias=''

    ## ----------- ##
    ## confdefs.h. ##
    ## ----------- ##

    /* confdefs.h */
    #define PACKAGE_NAME "opus"
    #define PACKAGE_TARNAME "opus"
    #define PACKAGE_VERSION "1.1.5"
    #define PACKAGE_STRING "opus 1.1.5"
    #define PACKAGE_BUGREPORT "opus@xiph.org"
    #define PACKAGE_URL ""

    configure: exit 77
  • Libavformat/FFMPEG : Muxing into mp4 with AVFormatContext drops the final frame, depending on the number of frames

    27 octobre 2020, par Galen Lynch

    I am trying to use libavformat to create a .mp4 video
with a single h.264 video stream, but the final frame in the resulting file
often has a duration of zero and is effectively dropped from the video.
Strangely enough, whether the final frame is dropped or not depends on how many
frames I try to add to the file. Some simple testing that I outline below makes
me think that I am somehow misconfiguring either the AVFormatContext or the
h.264 encoder, resulting in two edit lists that sometimes chop off the final
frame. I will also post a simplified version of the code I am using, in case I'm
making some obvious mistake. Any help would be greatly appreciated : I've been
struggling with this issue for the past few days and have made little progress.

    


    I can recover the dropped frame by creating a new mp4 container using ffmpeg
binary with the copy codec if I use the -ignore_editlist option. Inspecting
the file with a missing frame using ffprobe, mp4trackdump, or mp4file --dump, shows that the final frame is dropped if its sample time is exactly the
same the end of the edit list. When I make a file that has no dropped frames, it
still has two edit lists : the only difference is that the end time of the edit
list is beyond all samples in files that do not have dropped frames. Though this
is hardly a fair comparison, if I make a .png for each frame and then generate
a .mp4 with ffmpeg using the image2 codec and similar h.264 settings, I
produce a movie with all frames present, only one edit list, and similar PTS
times as my mangled movies with two edit lists. In this case, the edit list
always ends after the last frame/sample time.

    


    I am using this command to determine the number of frames in the resulting stream,
though I also get the same number with other utilities :

    


    ffprobe -v error -count_frames -select_streams v:0 -show_entries stream=nb_read_frames -of default=nokey=1:noprint_wrappers=1 video_file_name.mp4


    


    Simple inspection of the file with ffprobe shows no obviously alarming signs to
me, besides the framerate being affected by the missing frame (the target was
24) :

    


    $ ffprobe -hide_banner testing.mp4
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'testing.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.45.100
  Duration: 00:00:04.13, start: 0.041016, bitrate: 724 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 100x100, 722 kb/s, 24.24 fps, 24 tbr, 12288 tbn, 48 tbc (default)
    Metadata:
      handler_name    : VideoHandler


    


    The files that I generate programatically always have two edit lists, one of
which is very short. In files both with and without a missing frame, the
duration one of the frames is 0, while all the others have the same duration
(512). You can see this in the ffmpeg output for this file that I tried to put
100 frames into, though only 99 are visible despite the file containing all 100
samples.

    


    $ ffmpeg -hide_banner -y -v 9 -loglevel 99 -i testing.mp4  &#xA;...&#xA;<edited to="to" remove="remove" the="the" class="class" printing="printing">&#xA;type:&#x27;edts&#x27; parent:&#x27;trak&#x27; sz: 48 100 948&#xA;type:&#x27;elst&#x27; parent:&#x27;edts&#x27; sz: 40 8 40&#xA;track[0].edit_count = 2&#xA;duration=41 time=-1 rate=1.000000&#xA;duration=4125 time=0 rate=1.000000&#xA;type:&#x27;mdia&#x27; parent:&#x27;trak&#x27; sz: 808 148 948&#xA;type:&#x27;mdhd&#x27; parent:&#x27;mdia&#x27; sz: 32 8 800&#xA;type:&#x27;hdlr&#x27; parent:&#x27;mdia&#x27; sz: 45 40 800&#xA;ctype=[0][0][0][0]&#xA;stype=vide&#xA;type:&#x27;minf&#x27; parent:&#x27;mdia&#x27; sz: 723 85 800&#xA;type:&#x27;vmhd&#x27; parent:&#x27;minf&#x27; sz: 20 8 715&#xA;type:&#x27;dinf&#x27; parent:&#x27;minf&#x27; sz: 36 28 715&#xA;type:&#x27;dref&#x27; parent:&#x27;dinf&#x27; sz: 28 8 28&#xA;Unknown dref type 0x206c7275 size 12&#xA;type:&#x27;stbl&#x27; parent:&#x27;minf&#x27; sz: 659 64 715&#xA;type:&#x27;stsd&#x27; parent:&#x27;stbl&#x27; sz: 151 8 651&#xA;size=135 4CC=avc1 codec_type=0&#xA;type:&#x27;avcC&#x27; parent:&#x27;stsd&#x27; sz: 49 8 49&#xA;type:&#x27;stts&#x27; parent:&#x27;stbl&#x27; sz: 32 159 651&#xA;track[0].stts.entries = 2&#xA;sample_count=99, sample_duration=512&#xA;sample_count=1, sample_duration=0&#xA;...&#xA;AVIndex stream 0, sample 99, offset 5a0ed, dts 50688, size 3707, distance 0, keyframe 1&#xA;Processing st: 0, edit list 0 - media time: -1, duration: 504&#xA;Processing st: 0, edit list 1 - media time: 0, duration: 50688&#xA;type:&#x27;udta&#x27; parent:&#x27;moov&#x27; sz: 98 1072 1162&#xA;...&#xA;</edited>

    &#xA;

    The last frame has zero duration :

    &#xA;

    $ mp4trackdump -v testing.mp4&#xA;...&#xA;mp4file testing.mp4, track 1, samples 100, timescale 12288&#xA;sampleId      1, size  6943 duration      512 time        0 00:00:00.000 S&#xA;sampleId      2, size  3671 duration      512 time      512 00:00:00.041 S&#xA;...&#xA;sampleId     99, size  3687 duration      512 time    50176 00:00:04.083 S&#xA;sampleId    100, size  3707 duration        0 time    50688 00:00:04.125 S&#xA;

    &#xA;

    Non-mangled videos that I generate have similar structure, as you can see in&#xA;this video that had 99 input frames, all of which are visible in the output.&#xA;Even though the sample_duration is set to zero for one of the samples in the&#xA;stss box, it is not dropped from the frame count or when reading the frames back&#xA;in with ffmpeg.

    &#xA;

    $ ffmpeg -hide_banner -y -v 9 -loglevel 99 -i testing_99.mp4  &#xA;...&#xA;type:&#x27;elst&#x27; parent:&#x27;edts&#x27; sz: 40 8 40&#xA;track[0].edit_count = 2&#xA;duration=41 time=-1 rate=1.000000&#xA;duration=4084 time=0 rate=1.000000&#xA;...&#xA;track[0].stts.entries = 2&#xA;sample_count=98, sample_duration=512&#xA;sample_count=1, sample_duration=0&#xA;...&#xA;AVIndex stream 0, sample 98, offset 5d599, dts 50176, size 3833, distance 0, keyframe 1&#xA;Processing st: 0, edit list 0 - media time: -1, duration: 504&#xA;Processing st: 0, edit list 1 - media time: 0, duration: 50184&#xA;...&#xA;

    &#xA;

    $ mp4trackdump -v testing_99.mp4&#xA;...&#xA;sampleId     98, size  3814 duration      512 time    49664 00:00:04.041 S&#xA;sampleId     99, size  3833 duration        0 time    50176 00:00:04.083 S&#xA;

    &#xA;

    One difference that jumps out to me is that the mangled file's second edit list&#xA;ends at time 50688, which coincides with the last sample, while the non-mangled&#xA;file's edit list ends at 50184, which is after the time of the last sample&#xA;at 50176. As I mentioned before, whether the last frame is clipped depends on&#xA;the number of frames I encode and mux into the container : 100 input frames&#xA;results in 1 dropped frame, 99 results in 0, 98 in 0, 97 in 1, etc...

    &#xA;

    Here is the code that I used to generate these files, which is a MWE script&#xA;version of library functions that I am modifying. It is written in Julia,&#xA;which I do not think is important here, and calls the FFMPEG library version&#xA;4.3.1. It's more or less a direct translation from of the FFMPEG muxing&#xA;demo, although the codec&#xA;context here is created before the format context. I am presenting the code that&#xA;interacts with ffmpeg first, although it relies on some helper code that I will&#xA;put below.

    &#xA;

    The helper code just makes it easier to work with nested C structs in Julia, and&#xA;allows . syntax in Julia to be used in place of C's arrow (->) operator for&#xA;field access of struct pointers. Libav structs such as AVFrame appear as a&#xA;thin wrapper type AVFramePtr, and similarly AVStream appears as&#xA;AVStreamPtr etc... These act like single or double pointers for the purposes&#xA;of function calls, depending on the function's type signature. Hopefully it will&#xA;be clear enough to understand if you are familiar with working with libav in C,&#xA;and I don't think looking at the helper code should be necessary if you don't&#xA;want to run the code.

    &#xA;

    # Function to transfer array to AVPicture/AVFrame&#xA;function transfer_img_buf_to_frame!(frame, img)&#xA;    img_pointer = pointer(img)&#xA;    data_pointer = frame.data[1] # Base-1 indexing, get pointer to first data buffer in frame&#xA;    for h = 1:frame.height&#xA;        data_line_pointer = data_pointer &#x2B; (h-1) * frame.linesize[1] # base-1 indexing&#xA;        img_line_pointer = img_pointer &#x2B; (h-1) * frame.width&#xA;        unsafe_copyto!(data_line_pointer, img_line_pointer, frame.width) # base-1 indexing&#xA;    end&#xA;end&#xA;&#xA;# Function to transfer AVFrame to AVCodecContext, and AVPacket to AVFormatContext&#xA;function encode_mux!(packet, format_context, frame, codec_context; flush = false)&#xA;    if flush&#xA;        fret = avcodec_send_frame(codec_context, C_NULL)&#xA;    else&#xA;        fret = avcodec_send_frame(codec_context, frame)&#xA;    end&#xA;    if fret &lt; 0 &amp;&amp; !in(fret, [-Libc.EAGAIN, VIO_AVERROR_EOF])&#xA;        error("Error $fret sending a frame for encoding")&#xA;    end&#xA;&#xA;    pret = Cint(0)&#xA;    while pret >= 0&#xA;        pret = avcodec_receive_packet(codec_context, packet)&#xA;        if pret == -Libc.EAGAIN || pret == VIO_AVERROR_EOF&#xA;             break&#xA;        elseif pret &lt; 0&#xA;            error("Error $pret during encoding")&#xA;        end&#xA;        stream = format_context.streams[1] # Base-1 indexing&#xA;        av_packet_rescale_ts(packet, codec_context.time_base, stream.time_base)&#xA;        packet.stream_index = 0&#xA;        ret = av_interleaved_write_frame(format_context, packet)&#xA;        ret &lt; 0 &amp;&amp; error("Error muxing packet: $ret")&#xA;    end&#xA;    if !flush &amp;&amp; fret == -Libc.EAGAIN &amp;&amp; pret != VIO_AVERROR_EOF&#xA;        fret = avcodec_send_frame(codec_context, frame)&#xA;        if fret &lt; 0 &amp;&amp; fret != VIO_AVERROR_EOF&#xA;            error("Error $fret sending a frame for encoding")&#xA;        end&#xA;    end&#xA;    return pret&#xA;end&#xA;&#xA;# Set parameters of test movie&#xA;nframe = 100&#xA;width, height = 100, 100&#xA;framerate = 24&#xA;gop = 0&#xA;codec_name = "libx264"&#xA;filename = "testing.mp4"&#xA;&#xA;((width % 2 !=0) || (height % 2 !=0)) &amp;&amp; error("Encoding error: Image dims must be a multiple of two")&#xA;&#xA;# Make test images&#xA;imgstack = map(x->rand(UInt8,width,height),1:nframe);&#xA;&#xA;pix_fmt = AV_PIX_FMT_GRAY8&#xA;framerate_rat = Rational(framerate)&#xA;&#xA;codec = avcodec_find_encoder_by_name(codec_name)&#xA;codec == C_NULL &amp;&amp; error("Codec &#x27;$codec_name&#x27; not found")&#xA;&#xA;# Allocate AVCodecContext&#xA;codec_context_p = avcodec_alloc_context3(codec) # raw pointer&#xA;codec_context_p == C_NULL &amp;&amp; error("Could not allocate AVCodecContext")&#xA;# Easier to work with pointer that acts like a c struct pointer, type defined below&#xA;codec_context = AVCodecContextPtr(codec_context_p)&#xA;&#xA;codec_context.width = width&#xA;codec_context.height = height&#xA;codec_context.time_base = AVRational(1/framerate_rat)&#xA;codec_context.framerate = AVRational(framerate_rat)&#xA;codec_context.pix_fmt = pix_fmt&#xA;codec_context.gop_size = gop&#xA;&#xA;ret = avcodec_open2(codec_context, codec, C_NULL)&#xA;ret &lt; 0 &amp;&amp; error("Could not open codec: Return code $(ret)")&#xA;&#xA;# Allocate AVFrame and wrap it in a Julia convenience type&#xA;frame_p = av_frame_alloc()&#xA;frame_p == C_NULL &amp;&amp; error("Could not allocate AVFrame")&#xA;frame = AVFramePtr(frame_p)&#xA;&#xA;frame.format = pix_fmt&#xA;frame.width = width&#xA;frame.height = height&#xA;&#xA;# Allocate picture buffers for frame&#xA;ret = av_frame_get_buffer(frame, 0)&#xA;ret &lt; 0 &amp;&amp; error("Could not allocate the video frame data")&#xA;&#xA;# Allocate AVPacket and wrap it in a Julia convenience type&#xA;packet_p = av_packet_alloc()&#xA;packet_p == C_NULL &amp;&amp; error("Could not allocate AVPacket")&#xA;packet = AVPacketPtr(packet_p)&#xA;&#xA;# Allocate AVFormatContext and wrap it in a Julia convenience type&#xA;format_context_dp = Ref(Ptr{AVFormatContext}()) # double pointer&#xA;ret = avformat_alloc_output_context2(format_context_dp, C_NULL, C_NULL, filename)&#xA;if ret != 0 || format_context_dp[] == C_NULL&#xA;    error("Could not allocate AVFormatContext")&#xA;end&#xA;format_context = AVFormatContextPtr(format_context_dp)&#xA;&#xA;# Add video stream to AVFormatContext and configure it to use the encoder made above&#xA;stream_p = avformat_new_stream(format_context, C_NULL)&#xA;stream_p == C_NULL &amp;&amp; error("Could not allocate output stream")&#xA;stream = AVStreamPtr(stream_p) # Wrap this pointer in a convenience type&#xA;&#xA;stream.time_base = codec_context.time_base&#xA;stream.avg_frame_rate = 1 / convert(Rational, stream.time_base)&#xA;ret = avcodec_parameters_from_context(stream.codecpar, codec_context)&#xA;ret &lt; 0 &amp;&amp; error("Could not set parameters of stream")&#xA;&#xA;# Open the AVIOContext&#xA;pb_ptr = field_ptr(format_context, :pb)&#xA;# This following is just a call to avio_open, with a bit of extra protection&#xA;# so the Julia garbage collector does not destroy format_context during the call&#xA;ret = GC.@preserve format_context avio_open(pb_ptr, filename, AVIO_FLAG_WRITE)&#xA;ret &lt; 0 &amp;&amp; error("Could not open file $filename for writing")&#xA;&#xA;# Write the header&#xA;ret = avformat_write_header(format_context, C_NULL)&#xA;ret &lt; 0 &amp;&amp; error("Could not write header")&#xA;&#xA;# Encode and mux each frame&#xA;for i in 1:nframe # iterate from 1 to nframe&#xA;    img = imgstack[i] # base-1 indexing&#xA;    ret = av_frame_make_writable(frame)&#xA;    ret &lt; 0 &amp;&amp; error("Could not make frame writable")&#xA;    transfer_img_buf_to_frame!(frame, img)&#xA;    frame.pts = i&#xA;    encode_mux!(packet, format_context, frame, codec_context)&#xA;end&#xA;&#xA;# Flush the encoder&#xA;encode_mux!(packet, format_context, frame, codec_context; flush = true)&#xA;&#xA;# Write the trailer&#xA;av_write_trailer(format_context)&#xA;&#xA;# Close the AVIOContext&#xA;pb_ptr = field_ptr(format_context, :pb) # get pointer to format_context.pb&#xA;ret = GC.@preserve format_context avio_closep(pb_ptr) # simply a call to avio_closep&#xA;ret &lt; 0 &amp;&amp; error("Could not free AVIOContext")&#xA;&#xA;# Deallocation&#xA;avcodec_free_context(codec_context)&#xA;av_frame_free(frame)&#xA;av_packet_free(packet)&#xA;avformat_free_context(format_context)&#xA;

    &#xA;

    Below is the helper code that makes accessing pointers to nested c structs not a&#xA;total pain in Julia. If you try to run the code yourself, please enter this in&#xA;before the logic of the code shown above. It requires&#xA;VideoIO.jl, a Julia wrapper to libav.

    &#xA;

    # Convenience type and methods to make the above code look more like C&#xA;using Base: RefValue, fieldindex&#xA;&#xA;import Base: unsafe_convert, getproperty, setproperty!, getindex, setindex!,&#xA;    unsafe_wrap, propertynames&#xA;&#xA;# VideoIO is a Julia wrapper to libav&#xA;#&#xA;# Bring bindings to libav library functions into namespace&#xA;using VideoIO: AVCodecContext, AVFrame, AVPacket, AVFormatContext, AVRational,&#xA;    AVStream, AV_PIX_FMT_GRAY8, AVIO_FLAG_WRITE, AVFMT_NOFILE,&#xA;    avformat_alloc_output_context2, avformat_free_context, avformat_new_stream,&#xA;    av_dump_format, avio_open, avformat_write_header,&#xA;    avcodec_parameters_from_context, av_frame_make_writable, avcodec_send_frame,&#xA;    avcodec_receive_packet, av_packet_rescale_ts, av_interleaved_write_frame,&#xA;    avformat_query_codec, avcodec_find_encoder_by_name, avcodec_alloc_context3,&#xA;    avcodec_open2, av_frame_alloc, av_frame_get_buffer, av_packet_alloc,&#xA;    avio_closep, av_write_trailer, avcodec_free_context, av_frame_free,&#xA;    av_packet_free&#xA;&#xA;# Submodule of VideoIO&#xA;using VideoIO: AVCodecs&#xA;&#xA;# Need to import this function from Julia&#x27;s Base to add more methods&#xA;import Base: convert&#xA;&#xA;const VIO_AVERROR_EOF = -541478725 # AVERROR_EOF&#xA;&#xA;# Methods to convert between AVRational and Julia&#x27;s Rational type, because it&#x27;s&#xA;# hard to access the AV rational macros with Julia&#x27;s C interface&#xA;convert(::Type{Rational{T}}, r::AVRational) where T = Rational{T}(r.num, r.den)&#xA;convert(::Type{Rational}, r::AVRational) = Rational(r.num, r.den)&#xA;convert(::Type{AVRational}, r::Rational) = AVRational(numerator(r), denominator(r))&#xA;&#xA;"""&#xA;    mutable struct NestedCStruct{T}&#xA;&#xA;Wraps a pointer to a C struct, and acts like a double pointer to that memory.&#xA;The methods below will automatically convert it to a single pointer if needed&#xA;for a function call, and make interacting with it in Julia look (more) similar&#xA;to interacting with it in C, except &#x27;->&#x27; in C is replaced by &#x27;.&#x27; in Julia.&#xA;"""&#xA;mutable struct NestedCStruct{T}&#xA;    data::RefValue{Ptr{T}}&#xA;end&#xA;NestedCStruct{T}(a::Ptr) where T = NestedCStruct{T}(Ref(a))&#xA;NestedCStruct(a::Ptr{T}) where T = NestedCStruct{T}(a)&#xA;&#xA;const AVCodecContextPtr = NestedCStruct{AVCodecContext}&#xA;const AVFramePtr = NestedCStruct{AVFrame}&#xA;const AVPacketPtr = NestedCStruct{AVPacket}&#xA;const AVFormatContextPtr = NestedCStruct{AVFormatContext}&#xA;const AVStreamPtr = NestedCStruct{AVStream}&#xA;&#xA;function field_ptr(::Type{S}, struct_pointer::Ptr{T}, field::Symbol,&#xA;                           index::Integer = 1) where {S,T}&#xA;    fieldpos = fieldindex(T, field)&#xA;    field_pointer = convert(Ptr{S}, struct_pointer) &#x2B;&#xA;        fieldoffset(T, fieldpos) &#x2B; (index - 1) * sizeof(S)&#xA;    return field_pointer&#xA;end&#xA;&#xA;field_ptr(a::Ptr{T}, field::Symbol, args...) where T =&#xA;    field_ptr(fieldtype(T, field), a, field, args...)&#xA;&#xA;function check_ptr_valid(p::Ptr, err::Bool = true)&#xA;    valid = p != C_NULL&#xA;    err &amp;&amp; !valid &amp;&amp; error("Invalid pointer")&#xA;    valid&#xA;end&#xA;&#xA;unsafe_convert(::Type{Ptr{T}}, ap::NestedCStruct{T}) where T =&#xA;    getfield(ap, :data)[]&#xA;unsafe_convert(::Type{Ptr{Ptr{T}}}, ap::NestedCStruct{T}) where T =&#xA;    unsafe_convert(Ptr{Ptr{T}}, getfield(ap, :data))&#xA;&#xA;function check_ptr_valid(a::NestedCStruct{T}, args...) where T&#xA;    p = unsafe_convert(Ptr{T}, a)&#xA;    GC.@preserve a check_ptr_valid(p, args...)&#xA;end&#xA;&#xA;nested_wrap(x::Ptr{T}) where T = NestedCStruct(x)&#xA;nested_wrap(x) = x&#xA;&#xA;function getproperty(ap::NestedCStruct{T}, s::Symbol) where T&#xA;    check_ptr_valid(ap)&#xA;    p = unsafe_convert(Ptr{T}, ap)&#xA;    res = GC.@preserve ap unsafe_load(field_ptr(p, s))&#xA;    nested_wrap(res)&#xA;end&#xA;&#xA;function setproperty!(ap::NestedCStruct{T}, s::Symbol, x) where T&#xA;    check_ptr_valid(ap)&#xA;    p = unsafe_convert(Ptr{T}, ap)&#xA;    fp = field_ptr(p, s)&#xA;    GC.@preserve ap unsafe_store!(fp, x)&#xA;end&#xA;&#xA;function getindex(ap::NestedCStruct{T}, i::Integer) where T&#xA;    check_ptr_valid(ap)&#xA;    p = unsafe_convert(Ptr{T}, ap)&#xA;    res = GC.@preserve ap unsafe_load(p, i)&#xA;    nested_wrap(res)&#xA;end&#xA;&#xA;function setindex!(ap::NestedCStruct{T}, i::Integer, x) where T&#xA;    check_ptr_valid(ap)&#xA;    p = unsafe_convert(Ptr{T}, ap)&#xA;    GC.@preserve ap unsafe_store!(p, x, i)&#xA;end&#xA;&#xA;function unsafe_wrap(::Type{T}, ap::NestedCStruct{S}, i) where {S, T}&#xA;    check_ptr_valid(ap)&#xA;    p = unsafe_convert(Ptr{S}, ap)&#xA;    GC.@preserve ap unsafe_wrap(T, p, i)&#xA;end&#xA;&#xA;function field_ptr(::Type{S}, a::NestedCStruct{T}, field::Symbol,&#xA;                           args...) where {S, T}&#xA;    check_ptr_valid(a)&#xA;    p = unsafe_convert(Ptr{T}, a)&#xA;    GC.@preserve a field_ptr(S, p, field, args...)&#xA;end&#xA;&#xA;field_ptr(a::NestedCStruct{T}, field::Symbol, args...) where T =&#xA;    field_ptr(fieldtype(T, field), a, field, args...)&#xA;&#xA;propertynames(ap::T) where {S, T&lt;:NestedCStruct{S}} = (fieldnames(S)...,&#xA;                                                       fieldnames(T)...)&#xA;

    &#xA;


    &#xA;

    Edit : Some things that I have already tried

    &#xA;

      &#xA;
    • Explicitly setting the stream duration to be the same number as the number of frames that I add, or a few more beyond that
    • &#xA;

    • Explicitly setting the stream start time to zero, while the first frame has a PTS of 1
    • &#xA;

    • Playing around with encoder parameters, as well as gop_size, using B frames, etc.
    • &#xA;

    • Setting the private data for the mov/mp4 muxer to set the movflag negative_cts_offsets
    • &#xA;

    • Changing the framerate
    • &#xA;

    • Tried different pixel formats, such as AV_PIX_FMT_YUV420P
    • &#xA;

    &#xA;

    Also to be clear while I can just transfer the file into another while ignoring the edit lists to work around this problem, I am hoping to not make damaged mp4 files in the first place.

    &#xA;

  • Introducing Crash Analytics for Matomo

    30 août 2023, par Erin — Community, Plugins

    Bugs and development go hand in hand. As code matures, it contends with new browser iterations, clashes with ad blockers and other software quirks, resulting in the inevitable emergence of bugs. In fact, a staggering 13% of all pageviews come with lurking JavaScript errors.

    Monitoring for crashes becomes an unrelenting task. Amidst this never-ending effort to remove bugs, a SurveyMonkey study unveils a shared reality : a resounding 66% of individuals have encountered bug-ridden websites.

    These bugs lead to problems like malfunctioning shopping carts, glitchy checkout procedures and contact forms that just won’t cooperate. But they’re not just minor annoyances – they pose a real danger to your conversion rates and revenue.

    According to a study, 58% of visitors are inclined to abandon purchases as a result of bugs, while an astonishing 75% are driven to completely abandon websites due to these frustrating experiences.

    Imagine a website earning approximately 25,000 EUR per month. Now, factor in errors occurring in 13% of all pageviews. The result ? A potential monthly loss of 1,885 EUR.

    Meet Crash Analytics

    Driven by our vision to create an empowering analytics product, we’re excited to introduce Crash Analytics, an innovative plugin for Matomo On-Premise that automatically tracks bugs on your website.

    Crash Analytics for Matomo Evolution Graph
    View crash reports by evolution over time

    By offering insights into the precise bug location and the user’s interactions that triggered it, along with details about their device type, browser and more, Crash Analytics empowers you to swiftly address crashes, leading to an improved user experience, higher conversion rates and revenue growth.

    Soon, Crash Analytics will become available to Matomo Cloud users as well, so stay tuned for further updates and announcements.

    Say goodbye to lost revenue – never miss a bug again

    Even if you put your website through the toughest tests, it’s hard to predict every little hiccup that can pop up across different browsers, setups and situations. Factors such as ad blockers, varying internet speeds for visitors and browser updates can add an extra layer of complexity.

    When these crashes happen, you want to know immediately. However, according to a study, only 29% of surveyed respondents would report the existence of the site bug to the website operator. These bugs that go unnoticed can really hurt your bottom line and conversion rates, causing you to lose out on revenue and leaving your users frustrated and disappointed.

    Crash detail report in Crash Analytics for Matomo
    Detailed crash report

    Crash Analytics is here to bridge this gap. Armed with scheduled reporting (via email or texts) and automated alert functionalities, you gain the power to instantly detect bugs as they occur on your site. This proactive approach ensures that even the subtlest of issues are brought to your attention promptly. 

    With automated reports and alerts, you can also opt to receive notifications when crashes increase or ignore specific crashes that you deem insignificant. This keeps you in the loop with only the issues that truly matter, helping you cut out the noise and take immediate action.

    Forward crash data

    Easily forward crash data to developers and synchronise the efforts of technical teams and marketing experts. Track emerging, disappearing and recurring errors, ensuring that crash data is efficiently relayed to developers to prioritise fixes that matter.

    Eemerging, disappearing and recurring crashes in Crash Analytics for Matomo
    Track emerging, disappearing and recurring bugs

    Plus, your finger is always on the pulse with real-time reports that offer a live view of crashes happening at the moment, an especially helpful feature after deploying changes. Use annotations to mark deploys and correlate them with crash data, enabling you to quickly identify if a new bug is linked to recent updates or modifications.

    Crash data in real time
    Crash data in real time

    And with our mobile app, you can effortlessly stay connected to your website’s performance, conveniently accessing crash information anytime and anywhere. This ensures you’re in complete control of your site’s health, even when you’re on the move.

    Streamline bug resolution with combined web and crash analytics

    Crash Analytics for Matomo doesn’t just stop at pinpointing bug locations ; it goes a step further by providing you with a holistic perspective of user interactions. Seamlessly combining Matomo’s traditional and behavioural web analytics features—like segments, session recordings and visitor logs—with crash data, this integrated approach unveils a wealth of insights so you can quickly resolve bugs. 

    For instance, let’s say a user encounters a bug while attempting to complete a purchase on your e-commerce website. Crash Analytics reveals the exact point of failure, but to truly grasp the situation, you delve into the session recordings. These recordings offer a front-row seat to the user’s journey—every click and interaction that led to the bug. Session recordings are especially helpful when you are struggling to reproduce an issue.

    Visits log combined with crash data in Matomo
    Visits log overlayed with crash data

    Additionally, the combination of visitor logs with crash data offers a comprehensive timeline of a user’s engagement. This helps you understand their activity leading up to the bug, such as pages visited, actions taken and devices used. Armed with these multifaceted insights, you can confidently pinpoint the root causes and address the crash immediately.

    With segments, you have the ability to dissect the data and compare experiences among distinct user groups. For example, you can compare mobile visitors to desktop visitors to determine if the issue is isolated or widespread and what impact the issue is having on the user experience of different user groups. 

    The combination of crash data with Matomo’s comprehensive web analytics equips you with the tools needed to elevate user experiences and ultimately drive revenue growth.

    Start in seconds, shape as needed : Your path to a 100% reliable website

    Crash Analytics makes the path to a reliable website simple. You don’t have to deal with intricate setups—crash detection starts without any configuration. 

    Plus, Crash Analytics excels in cross-stack proficiency, seamlessly extending its capabilities beyond automatically tracking JavaScript errors to covering server-side crashes as well, whether they occur in PHP, Android, iOS, Java or other frameworks. This versatile approach ensures that Crash Analytics comprehensively supports your website’s health and performance across various technological landscapes.

    Elevate your website with Crash Analytics

    Experience the seamless convergence of bug tracking and web analytics, allowing you to delve into user interactions, session recordings and visitor logs. With the flexibility of customising real-time alerts and scheduled reports, alongside cross-stack proficiency, Crash Analytics becomes your trusted ally in enhancing your website’s reliability and user satisfaction to increase conversions and drive revenue growth. Equip yourself to swiftly address issues and create a website where user experiences take precedence.

    Start your 30-day free trial of our Crash Analytics plugin today, and stay tuned for its availability on Matomo Cloud.