
Recherche avancée
Médias (1)
-
Bug de détection d’ogg
22 mars 2013, par
Mis à jour : Avril 2013
Langue : français
Type : Video
Autres articles (16)
-
Encoding and processing into web-friendly formats
13 avril 2011, parMediaSPIP automatically converts uploaded files to internet-compatible formats.
Video files are encoded in MP4, Ogv and WebM (supported by HTML5) and MP4 (supported by Flash).
Audio files are encoded in MP3 and Ogg (supported by HTML5) and MP3 (supported by Flash).
Where possible, text is analyzed in order to retrieve the data needed for search engine detection, and then exported as a series of image files.
All uploaded files are stored online in their original format, so you can (...) -
Demande de création d’un canal
12 mars 2010, parEn fonction de la configuration de la plateforme, l’utilisateur peu avoir à sa disposition deux méthodes différentes de demande de création de canal. La première est au moment de son inscription, la seconde, après son inscription en remplissant un formulaire de demande.
Les deux manières demandent les mêmes choses fonctionnent à peu près de la même manière, le futur utilisateur doit remplir une série de champ de formulaire permettant tout d’abord aux administrateurs d’avoir des informations quant à (...) -
Installation en mode ferme
4 février 2011, parLe mode ferme permet d’héberger plusieurs sites de type MediaSPIP en n’installant qu’une seule fois son noyau fonctionnel.
C’est la méthode que nous utilisons sur cette même plateforme.
L’utilisation en mode ferme nécessite de connaïtre un peu le mécanisme de SPIP contrairement à la version standalone qui ne nécessite pas réellement de connaissances spécifique puisque l’espace privé habituel de SPIP n’est plus utilisé.
Dans un premier temps, vous devez avoir installé les mêmes fichiers que l’installation (...)
Sur d’autres sites (3628)
-
Android ffmpeg with libx264 - undefined references
5 décembre 2015, par Krzysztof KansyI’m building ffmpeg for Android with libx264 using appunite’s project under Ubuntu 15.10. I’ve build it without libx264 properly, but adding the library keep giving me
undefined reference to 'x264_picture_init'
and multiple other similar errors. I tried variety of possible solutions from mailing lists/other SO questions, but still nothing helps me solving the problem.I have removed ffmpeg/libx264/libx264-dev packages to avoid possible duplicate libraries in the system. I’ve got the libx264.a library in ffmpeg-build/ARCH/lib, where the other built libraries lives. Also I don’t think this is caused by header file not matching the library, because the only x264.h header in the system is the one used for the library building.
Here is my build_android.sh.
set -x
if [ "$ANDROID_NDK_HOME" = "" ]; then
echo ANDROID_NDK_HOME variable not set, exiting
echo "Use: export ANDROID_NDK_HOME=/your/path/to/android-ndk"
exit 1
fi
# Get the newest arm-linux-androideabi version
if [ -z "$COMPILATOR_VERSION" ]; then
DIRECTORIES=$ANDROID_NDK_HOME/toolchains/arm-linux-androideabi-*
for i in $DIRECTORIES; do
PROPOSED_NAME=${i#*$ANDROID_NDK_HOME/toolchains/arm-linux-androideabi-}
if [[ $PROPOSED_NAME =~ ^[0-9\.]+$ ]] ; then
echo "Available compilator version: $PROPOSED_NAME"
COMPILATOR_VERSION=$PROPOSED_NAME
fi
done
fi
if [ -z "$COMPILATOR_VERSION" ]; then
echo "Could not find compilator"
exit 1
fi
if [ ! -d $ANDROID_NDK_HOME/toolchains/arm-linux-androideabi-$COMPILATOR_VERSION ]; then
echo $ANDROID_NDK_HOME/toolchains/arm-linux-androideabi-$COMPILATOR_VERSION does not exist
exit 1
fi
echo "Using compilator version: $COMPILATOR_VERSION"
OS_ARCH=`basename $ANDROID_NDK_HOME/toolchains/arm-linux-androideabi-$COMPILATOR_VERSION/prebuilt/*`
echo "Using architecture: $OS_ARCH"
function setup_paths
{
export PLATFORM=$ANDROID_NDK_HOME/platforms/$PLATFORM_VERSION/arch-$ARCH/
if [ ! -d $PLATFORM ]; then
echo $PLATFORM does not exist
exit 1
fi
echo "Using platform: $PLATFORM"
export PATH=${PATH}:$PREBUILT/bin/
export CROSS_COMPILE=$PREBUILT/bin/$EABIARCH-
export CFLAGS=$OPTIMIZE_CFLAGS
export CPPFLAGS="$CFLAGS"
export CFLAGS="$CFLAGS"
export CXXFLAGS="$CFLAGS"
export CXX="${CROSS_COMPILE}g++ --sysroot=$PLATFORM"
export AS="${CROSS_COMPILE}gcc --sysroot=$PLATFORM"
export CC="${CROSS_COMPILE}gcc --sysroot=$PLATFORM"
export PKG_CONFIG="${CROSS_COMPILE}pkg-config"
export LD="${CROSS_COMPILE}ld"
export NM="${CROSS_COMPILE}nm"
export STRIP="${CROSS_COMPILE}strip"
export RANLIB="${CROSS_COMPILE}ranlib"
export AR="${CROSS_COMPILE}ar"
export LDFLAGS="-Wl,-rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -nostdlib -lc -lm -ldl -llog"
export PKG_CONFIG_LIBDIR=$PREFIX/lib/pkgconfig/
export PKG_CONFIG_PATH=$PREFIX/lib/pkgconfig/
if [ ! -f "${CROSS_COMPILE}gcc" ]; then
echo "Gcc does not exists in path: ${CROSS_COMPILE}gcc"
exit 1;
fi
if [ ! -f "${PKG_CONFIG}" ]; then
echo "Pkg config does not exists in path: ${PKG_CONFIG} - Probably BUG in NDK but..."
set +e
SYS_PKG_CONFIG=$(which pkg-config)
if [ "$?" -ne 0 ]; then
echo "This system does not contain system pkg-config, so we can do anything"
exit 1
fi
set -e
cat > $PKG_CONFIG << EOF
#!/bin/bash
pkg-config \$*
EOF
chmod u+x $PKG_CONFIG
echo "Because we have local pkg-config we will create it in ${PKG_CONFIG} directory using ${SYS_PKG_CONFIG}"
fi
}
function build_x264
{
echo "Starting build x264 for $ARCH"
cd x264
./configure --prefix=$PREFIX --host=$ARCH-linux --enable-static --disable-shared --enable-pic --disable-cli $ADDITIONAL_CONFIGURE_FLAG
make clean
make -j4 install
make clean
cd ..
echo "FINISHED x264 for $ARCH"
}
function build_amr
{
echo "Starting build amr for $ARCH"
cd vo-amrwbenc
./configure \
--prefix=$PREFIX \
--host=$ARCH-linux \
--disable-dependency-tracking \
--disable-shared \
--enable-static \
--with-pic \
$ADDITIONAL_CONFIGURE_FLAG
make clean
make -j4 install
make clean
cd ..
echo "FINISHED amr for $ARCH"
}
function build_aac
{
echo "Starting build aac for $ARCH"
cd vo-aacenc
./configure \
--prefix=$PREFIX \
--host=$ARCH-linux \
--disable-dependency-tracking \
--disable-shared \
--enable-static \
--with-pic \
$ADDITIONAL_CONFIGURE_FLAG
make clean
make -j4 install
make clean
cd ..
echo "FINISHED aac for $ARCH"
}
function build_freetype2
{
echo "Starting build freetype2 for $ARCH"
cd freetype2
./configure \
--prefix=$PREFIX \
--host=$ARCH-linux \
--disable-dependency-tracking \
--disable-shared \
--enable-static \
--with-pic \
$ADDITIONAL_CONFIGURE_FLAG
make clean
make -j4 install
make clean
cd ..
echo "FINISHED freetype2 for $ARCH"
}
function build_ass
{
echo "Starting build ass for $ARCH"
cd libass
./configure \
--prefix=$PREFIX \
--host=$ARCH-linux \
--disable-fontconfig \
--disable-dependency-tracking \
--disable-shared \
--enable-static \
--with-pic \
$ADDITIONAL_CONFIGURE_FLAG
make clean
make V=1 -j4 install
make clean
cd ..
echo "FINISHED ass for $ARCH"
}
function build_fribidi
{
echo "Starting build fribidi for $ARCH"
cd fribidi
./configure \
--prefix=$PREFIX \
--host=$ARCH-linux \
--disable-bin \
--disable-dependency-tracking \
--disable-shared \
--enable-static \
--with-pic \
$ADDITIONAL_CONFIGURE_FLAG
make clean
make -j4 install
make clean
cd ..
echo "FINISHED fribidi for $ARCH"
}
function build_ffmpeg
{
echo "Starting build ffmpeg for $ARCH"
cd ffmpeg
./configure --target-os=linux \
--prefix=$PREFIX \
--enable-cross-compile \
--extra-libs="-lgcc -L$PREFIX/lib/libx264.a" \
--arch=$ARCH \
--cc=$CC \
--cross-prefix=$CROSS_COMPILE \
--nm=$NM \
--sysroot=$PLATFORM \
--extra-cflags=" -O3 -fpic -DANDROID -DHAVE_SYS_UIO_H=1 -Dipv6mr_interface=ipv6mr_ifindex -fasm -Wno-psabi -fno-short-enums -fno-strict-aliasing -finline-limit=300 $OPTIMIZE_CFLAGS" \
--disable-shared \
--enable-static \
--enable-runtime-cpudetect \
--pkg-config-flags="--static" \
--extra-ldflags="-Wl,-rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -nostdlib -lc -lm -ldl -llog -L$PREFIX/lib" \
--extra-cflags="-I$PREFIX/include" \
--disable-everything \
--enable-gpl \
--enable-pthreads \
--enable-libass \
--enable-libvo-aacenc \
--enable-libvo-amrwbenc \
--enable-hwaccel=h264_vaapi \
--enable-hwaccel=h264_vaapi \
--enable-hwaccel=h264_dxva2 \
--enable-hwaccel=mpeg4_vaapi \
--enable-libx264 \
--enable-demuxer=mov \
--enable-demuxer=h264 \
--enable-muxer=h264 \
--enable-demuxer=mpegvideo \
--enable-demuxer=h263 \
--enable-demuxer=mpegps \
--enable-demuxer=mjpeg \
--enable-demuxer=rtsp \
--enable-demuxer=rtp \
--enable-demuxer=hls \
--enable-demuxer=matroska \
--enable-muxer=rtsp \
--enable-muxer=mp4 \
--enable-muxer=mov \
--enable-muxer=mjpeg \
--enable-muxer=matroska \
--enable-protocol=crypto \
--enable-protocol=jni \
--enable-protocol=file \
--enable-protocol=rtp \
--enable-protocol=tcp \
--enable-protocol=udp \
--enable-protocol=applehttp \
--enable-protocol=hls \
--enable-protocol=http \
--enable-decoder=xsub \
--enable-decoder=jacosub \
--enable-decoder=dvdsub \
--enable-decoder=dvbsub \
--enable-decoder=subviewer \
--enable-decoder=rawvideo \
--enable-encoder=rawvideo \
--enable-decoder=mjpeg \
--enable-encoder=mjpeg \
--enable-decoder=h263 \
--enable-decoder=mpeg4 \
--enable-encoder=mpeg4 \
--enable-decoder=h264 \
--enable-encoder=h264 \
--enable-decoder=aac \
--enable-encoder=aac \
--enable-parser=h264 \
--enable-encoder=mp2 \
--enable-decoder=mp2 \
--enable-encoder=libvo_amrwbenc \
--enable-decoder=amrwb \
--enable-muxer=mp2 \
--enable-bsfs \
--enable-decoders \
--enable-encoders \
--enable-parsers \
--enable-hwaccels \
--enable-muxers \
--enable-avformat \
--enable-avcodec \
--enable-avresample \
--enable-zlib \
--disable-doc \
--disable-ffplay \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--enable-avfilter \
--disable-avdevice \
--disable-opencl \
--enable-nonfree \
--enable-version3 \
--enable-memalign-hack \
--enable-asm \
$ADDITIONAL_CONFIGURE_FLAG
make clean
make -j4 install
make clean
cd ..
echo "FINISHED ffmpeg for $ARCH"
}
function build_one {
echo "Starting build one for $ARCH"
cd ffmpeg
${LD} -rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -L$PREFIX/lib -soname $SONAME -shared -nostdlib -Bsymbolic --whole-archive --no-undefined -o $OUT_LIBRARY -lavformat -lavcodec -lavresample -lavutil -lswresample -lavfilter -lass -lfreetype -lfribidi -lswscale -lvo-aacenc -lvo-amrwbenc -lc -lm -lz -ldl -llog --dynamic-linker=/system/bin/linker -zmuldefs $PREBUILT/lib/gcc/$EABIARCH/$COMPILATOR_VERSION/libgcc.a
cd ..
echo "FINISHED one for $ARCH"
}
# enable additional architectures later on
#arm v5
#EABIARCH=arm-linux-androideabi
#ARCH=arm
#CPU=armv5
#OPTIMIZE_CFLAGS="-marm -march=$CPU"
#PREFIX=$(pwd)/ffmpeg-build/armeabi
#OUT_LIBRARY=$PREFIX/libffmpeg.so
#ADDITIONAL_CONFIGURE_FLAG=
#SONAME=libffmpeg.so
#PREBUILT=$ANDROID_NDK_HOME/toolchains/arm-linux-androideabi-$COMPILATOR_VERSION/prebuilt/$OS_ARCH
#PLATFORM_VERSION=android-5
#setup_paths
#build_amr
#build_aac
#build_fribidi
#build_freetype2
#build_ass
#build_ffmpeg
#build_one
#x86
#EABIARCH=i686-linux-android
#ARCH=x86
#OPTIMIZE_CFLAGS="-m32"
#PREFIX=$(pwd)/ffmpeg-build/x86
#OUT_LIBRARY=$PREFIX/libffmpeg.so
#ADDITIONAL_CONFIGURE_FLAG=--disable-asm
#SONAME=libffmpeg.so
#PREBUILT=$ANDROID_NDK_HOME/toolchains/x86-$COMPILATOR_VERSION/prebuilt/$OS_ARCH
#PLATFORM_VERSION=android-9
#setup_paths
#build_amr
#build_aac
#build_fribidi
#build_freetype2
#build_ass
#build_ffmpeg
#build_one
#mips
#EABIARCH=mipsel-linux-android
#ARCH=mips
#OPTIMIZE_CFLAGS="-EL -march=mips32 -mips32 -mhard-float"
#PREFIX=$(pwd)/ffmpeg-build/mips
#OUT_LIBRARY=$PREFIX/libffmpeg.so
#ADDITIONAL_CONFIGURE_FLAG="--disable-mips32r2"
#SONAME=libffmpeg.so
#PREBUILT=$ANDROID_NDK_HOME/toolchains/mipsel-linux-android-$COMPILATOR_VERSION/prebuilt/$OS_ARCH
#PLATFORM_VERSION=android-9
#setup_paths
#build_amr
#build_aac
#build_fribidi
#build_freetype2
#build_ass
#build_ffmpeg
#build_one
#arm v7vfpv3
EABIARCH=arm-linux-androideabi
ARCH=arm
CPU=armv7-a
OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=vfpv3-d16 -marm -march=$CPU "
PREFIX=$(pwd)/ffmpeg-build/armeabi-v7a
OUT_LIBRARY=$PREFIX/libffmpeg.so
ADDITIONAL_CONFIGURE_FLAG=
SONAME=libffmpeg.so
PREBUILT=$ANDROID_NDK_HOME/toolchains/arm-linux-androideabi-$COMPILATOR_VERSION/prebuilt/$OS_ARCH
PLATFORM_VERSION=android-5
setup_paths
build_x264
build_amr
build_aac
build_fribidi
build_freetype2
build_ass
build_ffmpeg
build_one
#arm v7 + neon (neon also include vfpv3-32)
EABIARCH=arm-linux-androideabi
ARCH=arm
CPU=armv7-a
OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=neon -marm -march=$CPU -mtune=cortex-a8 -mthumb -D__thumb__ "
PREFIX=$(pwd)/ffmpeg-build/armeabi-v7a-neon
OUT_LIBRARY=../ffmpeg-build/armeabi-v7a/libffmpeg-neon.so
ADDITIONAL_CONFIGURE_FLAG=--enable-neon
SONAME=libffmpeg-neon.so
PREBUILT=$ANDROID_NDK_HOME/toolchains/arm-linux-androideabi-$COMPILATOR_VERSION/prebuilt/$OS_ARCH
PLATFORM_VERSION=android-9
setup_paths
build_x264
build_amr
build_aac
build_fribidi
build_freetype2
build_ass
build_ffmpeg
build_one
echo "BUILD SUCCESS"I’ve disabled the non-arm architectures for the time being. If there is any other information I can provide to help finding the problem, I will be happy to do so.
I’m wondering if the issue may be caused by something missing in the script, namely in build_one part, tho I tried to indicate the libx264.a directly in —extra-ldflags, without success.
-
Android ffmpeg with libx264 - undefined references
5 décembre 2015, par Krzysztof KansyI’m building ffmpeg for Android with libx264 using appunite’s project under Ubuntu 15.10. I’ve build it without libx264 properly, but adding the library keep giving me
undefined reference to 'x264_picture_init'
and multiple other similar errors. I tried variety of possible solutions from mailing lists/other SO questions, but still nothing helps me solving the problem.I have removed ffmpeg/libx264/libx264-dev packages to avoid possible duplicate libraries in the system. I’ve got the libx264.a library in ffmpeg-build/ARCH/lib, where the other built libraries lives. Also I don’t think this is caused by header file not matching the library, because the only x264.h header in the system is the one used for the library building.
Here is my build_android.sh.
set -x
if [ "$ANDROID_NDK_HOME" = "" ]; then
echo ANDROID_NDK_HOME variable not set, exiting
echo "Use: export ANDROID_NDK_HOME=/your/path/to/android-ndk"
exit 1
fi
# Get the newest arm-linux-androideabi version
if [ -z "$COMPILATOR_VERSION" ]; then
DIRECTORIES=$ANDROID_NDK_HOME/toolchains/arm-linux-androideabi-*
for i in $DIRECTORIES; do
PROPOSED_NAME=${i#*$ANDROID_NDK_HOME/toolchains/arm-linux-androideabi-}
if [[ $PROPOSED_NAME =~ ^[0-9\.]+$ ]] ; then
echo "Available compilator version: $PROPOSED_NAME"
COMPILATOR_VERSION=$PROPOSED_NAME
fi
done
fi
if [ -z "$COMPILATOR_VERSION" ]; then
echo "Could not find compilator"
exit 1
fi
if [ ! -d $ANDROID_NDK_HOME/toolchains/arm-linux-androideabi-$COMPILATOR_VERSION ]; then
echo $ANDROID_NDK_HOME/toolchains/arm-linux-androideabi-$COMPILATOR_VERSION does not exist
exit 1
fi
echo "Using compilator version: $COMPILATOR_VERSION"
OS_ARCH=`basename $ANDROID_NDK_HOME/toolchains/arm-linux-androideabi-$COMPILATOR_VERSION/prebuilt/*`
echo "Using architecture: $OS_ARCH"
function setup_paths
{
export PLATFORM=$ANDROID_NDK_HOME/platforms/$PLATFORM_VERSION/arch-$ARCH/
if [ ! -d $PLATFORM ]; then
echo $PLATFORM does not exist
exit 1
fi
echo "Using platform: $PLATFORM"
export PATH=${PATH}:$PREBUILT/bin/
export CROSS_COMPILE=$PREBUILT/bin/$EABIARCH-
export CFLAGS=$OPTIMIZE_CFLAGS
export CPPFLAGS="$CFLAGS"
export CFLAGS="$CFLAGS"
export CXXFLAGS="$CFLAGS"
export CXX="${CROSS_COMPILE}g++ --sysroot=$PLATFORM"
export AS="${CROSS_COMPILE}gcc --sysroot=$PLATFORM"
export CC="${CROSS_COMPILE}gcc --sysroot=$PLATFORM"
export PKG_CONFIG="${CROSS_COMPILE}pkg-config"
export LD="${CROSS_COMPILE}ld"
export NM="${CROSS_COMPILE}nm"
export STRIP="${CROSS_COMPILE}strip"
export RANLIB="${CROSS_COMPILE}ranlib"
export AR="${CROSS_COMPILE}ar"
export LDFLAGS="-Wl,-rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -nostdlib -lc -lm -ldl -llog"
export PKG_CONFIG_LIBDIR=$PREFIX/lib/pkgconfig/
export PKG_CONFIG_PATH=$PREFIX/lib/pkgconfig/
if [ ! -f "${CROSS_COMPILE}gcc" ]; then
echo "Gcc does not exists in path: ${CROSS_COMPILE}gcc"
exit 1;
fi
if [ ! -f "${PKG_CONFIG}" ]; then
echo "Pkg config does not exists in path: ${PKG_CONFIG} - Probably BUG in NDK but..."
set +e
SYS_PKG_CONFIG=$(which pkg-config)
if [ "$?" -ne 0 ]; then
echo "This system does not contain system pkg-config, so we can do anything"
exit 1
fi
set -e
cat > $PKG_CONFIG << EOF
#!/bin/bash
pkg-config \$*
EOF
chmod u+x $PKG_CONFIG
echo "Because we have local pkg-config we will create it in ${PKG_CONFIG} directory using ${SYS_PKG_CONFIG}"
fi
}
function build_x264
{
echo "Starting build x264 for $ARCH"
cd x264
./configure --prefix=$PREFIX --host=$ARCH-linux --enable-static --disable-shared --enable-pic --disable-cli $ADDITIONAL_CONFIGURE_FLAG
make clean
make -j4 install
make clean
cd ..
echo "FINISHED x264 for $ARCH"
}
function build_amr
{
echo "Starting build amr for $ARCH"
cd vo-amrwbenc
./configure \
--prefix=$PREFIX \
--host=$ARCH-linux \
--disable-dependency-tracking \
--disable-shared \
--enable-static \
--with-pic \
$ADDITIONAL_CONFIGURE_FLAG
make clean
make -j4 install
make clean
cd ..
echo "FINISHED amr for $ARCH"
}
function build_aac
{
echo "Starting build aac for $ARCH"
cd vo-aacenc
./configure \
--prefix=$PREFIX \
--host=$ARCH-linux \
--disable-dependency-tracking \
--disable-shared \
--enable-static \
--with-pic \
$ADDITIONAL_CONFIGURE_FLAG
make clean
make -j4 install
make clean
cd ..
echo "FINISHED aac for $ARCH"
}
function build_freetype2
{
echo "Starting build freetype2 for $ARCH"
cd freetype2
./configure \
--prefix=$PREFIX \
--host=$ARCH-linux \
--disable-dependency-tracking \
--disable-shared \
--enable-static \
--with-pic \
$ADDITIONAL_CONFIGURE_FLAG
make clean
make -j4 install
make clean
cd ..
echo "FINISHED freetype2 for $ARCH"
}
function build_ass
{
echo "Starting build ass for $ARCH"
cd libass
./configure \
--prefix=$PREFIX \
--host=$ARCH-linux \
--disable-fontconfig \
--disable-dependency-tracking \
--disable-shared \
--enable-static \
--with-pic \
$ADDITIONAL_CONFIGURE_FLAG
make clean
make V=1 -j4 install
make clean
cd ..
echo "FINISHED ass for $ARCH"
}
function build_fribidi
{
echo "Starting build fribidi for $ARCH"
cd fribidi
./configure \
--prefix=$PREFIX \
--host=$ARCH-linux \
--disable-bin \
--disable-dependency-tracking \
--disable-shared \
--enable-static \
--with-pic \
$ADDITIONAL_CONFIGURE_FLAG
make clean
make -j4 install
make clean
cd ..
echo "FINISHED fribidi for $ARCH"
}
function build_ffmpeg
{
echo "Starting build ffmpeg for $ARCH"
cd ffmpeg
./configure --target-os=linux \
--prefix=$PREFIX \
--enable-cross-compile \
--extra-libs="-lgcc -L$PREFIX/lib/libx264.a" \
--arch=$ARCH \
--cc=$CC \
--cross-prefix=$CROSS_COMPILE \
--nm=$NM \
--sysroot=$PLATFORM \
--extra-cflags=" -O3 -fpic -DANDROID -DHAVE_SYS_UIO_H=1 -Dipv6mr_interface=ipv6mr_ifindex -fasm -Wno-psabi -fno-short-enums -fno-strict-aliasing -finline-limit=300 $OPTIMIZE_CFLAGS" \
--disable-shared \
--enable-static \
--enable-runtime-cpudetect \
--pkg-config-flags="--static" \
--extra-ldflags="-Wl,-rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -nostdlib -lc -lm -ldl -llog -L$PREFIX/lib" \
--extra-cflags="-I$PREFIX/include" \
--disable-everything \
--enable-gpl \
--enable-pthreads \
--enable-libass \
--enable-libvo-aacenc \
--enable-libvo-amrwbenc \
--enable-hwaccel=h264_vaapi \
--enable-hwaccel=h264_vaapi \
--enable-hwaccel=h264_dxva2 \
--enable-hwaccel=mpeg4_vaapi \
--enable-libx264 \
--enable-demuxer=mov \
--enable-demuxer=h264 \
--enable-muxer=h264 \
--enable-demuxer=mpegvideo \
--enable-demuxer=h263 \
--enable-demuxer=mpegps \
--enable-demuxer=mjpeg \
--enable-demuxer=rtsp \
--enable-demuxer=rtp \
--enable-demuxer=hls \
--enable-demuxer=matroska \
--enable-muxer=rtsp \
--enable-muxer=mp4 \
--enable-muxer=mov \
--enable-muxer=mjpeg \
--enable-muxer=matroska \
--enable-protocol=crypto \
--enable-protocol=jni \
--enable-protocol=file \
--enable-protocol=rtp \
--enable-protocol=tcp \
--enable-protocol=udp \
--enable-protocol=applehttp \
--enable-protocol=hls \
--enable-protocol=http \
--enable-decoder=xsub \
--enable-decoder=jacosub \
--enable-decoder=dvdsub \
--enable-decoder=dvbsub \
--enable-decoder=subviewer \
--enable-decoder=rawvideo \
--enable-encoder=rawvideo \
--enable-decoder=mjpeg \
--enable-encoder=mjpeg \
--enable-decoder=h263 \
--enable-decoder=mpeg4 \
--enable-encoder=mpeg4 \
--enable-decoder=h264 \
--enable-encoder=h264 \
--enable-decoder=aac \
--enable-encoder=aac \
--enable-parser=h264 \
--enable-encoder=mp2 \
--enable-decoder=mp2 \
--enable-encoder=libvo_amrwbenc \
--enable-decoder=amrwb \
--enable-muxer=mp2 \
--enable-bsfs \
--enable-decoders \
--enable-encoders \
--enable-parsers \
--enable-hwaccels \
--enable-muxers \
--enable-avformat \
--enable-avcodec \
--enable-avresample \
--enable-zlib \
--disable-doc \
--disable-ffplay \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--enable-avfilter \
--disable-avdevice \
--disable-opencl \
--enable-nonfree \
--enable-version3 \
--enable-memalign-hack \
--enable-asm \
$ADDITIONAL_CONFIGURE_FLAG
make clean
make -j4 install
make clean
cd ..
echo "FINISHED ffmpeg for $ARCH"
}
function build_one {
echo "Starting build one for $ARCH"
cd ffmpeg
${LD} -rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -L$PREFIX/lib -soname $SONAME -shared -nostdlib -Bsymbolic --whole-archive --no-undefined -o $OUT_LIBRARY -lavformat -lavcodec -lavresample -lavutil -lswresample -lavfilter -lass -lfreetype -lfribidi -lswscale -lvo-aacenc -lvo-amrwbenc -lc -lm -lz -ldl -llog --dynamic-linker=/system/bin/linker -zmuldefs $PREBUILT/lib/gcc/$EABIARCH/$COMPILATOR_VERSION/libgcc.a
cd ..
echo "FINISHED one for $ARCH"
}
# enable additional architectures later on
#arm v5
#EABIARCH=arm-linux-androideabi
#ARCH=arm
#CPU=armv5
#OPTIMIZE_CFLAGS="-marm -march=$CPU"
#PREFIX=$(pwd)/ffmpeg-build/armeabi
#OUT_LIBRARY=$PREFIX/libffmpeg.so
#ADDITIONAL_CONFIGURE_FLAG=
#SONAME=libffmpeg.so
#PREBUILT=$ANDROID_NDK_HOME/toolchains/arm-linux-androideabi-$COMPILATOR_VERSION/prebuilt/$OS_ARCH
#PLATFORM_VERSION=android-5
#setup_paths
#build_amr
#build_aac
#build_fribidi
#build_freetype2
#build_ass
#build_ffmpeg
#build_one
#x86
#EABIARCH=i686-linux-android
#ARCH=x86
#OPTIMIZE_CFLAGS="-m32"
#PREFIX=$(pwd)/ffmpeg-build/x86
#OUT_LIBRARY=$PREFIX/libffmpeg.so
#ADDITIONAL_CONFIGURE_FLAG=--disable-asm
#SONAME=libffmpeg.so
#PREBUILT=$ANDROID_NDK_HOME/toolchains/x86-$COMPILATOR_VERSION/prebuilt/$OS_ARCH
#PLATFORM_VERSION=android-9
#setup_paths
#build_amr
#build_aac
#build_fribidi
#build_freetype2
#build_ass
#build_ffmpeg
#build_one
#mips
#EABIARCH=mipsel-linux-android
#ARCH=mips
#OPTIMIZE_CFLAGS="-EL -march=mips32 -mips32 -mhard-float"
#PREFIX=$(pwd)/ffmpeg-build/mips
#OUT_LIBRARY=$PREFIX/libffmpeg.so
#ADDITIONAL_CONFIGURE_FLAG="--disable-mips32r2"
#SONAME=libffmpeg.so
#PREBUILT=$ANDROID_NDK_HOME/toolchains/mipsel-linux-android-$COMPILATOR_VERSION/prebuilt/$OS_ARCH
#PLATFORM_VERSION=android-9
#setup_paths
#build_amr
#build_aac
#build_fribidi
#build_freetype2
#build_ass
#build_ffmpeg
#build_one
#arm v7vfpv3
EABIARCH=arm-linux-androideabi
ARCH=arm
CPU=armv7-a
OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=vfpv3-d16 -marm -march=$CPU "
PREFIX=$(pwd)/ffmpeg-build/armeabi-v7a
OUT_LIBRARY=$PREFIX/libffmpeg.so
ADDITIONAL_CONFIGURE_FLAG=
SONAME=libffmpeg.so
PREBUILT=$ANDROID_NDK_HOME/toolchains/arm-linux-androideabi-$COMPILATOR_VERSION/prebuilt/$OS_ARCH
PLATFORM_VERSION=android-5
setup_paths
build_x264
build_amr
build_aac
build_fribidi
build_freetype2
build_ass
build_ffmpeg
build_one
#arm v7 + neon (neon also include vfpv3-32)
EABIARCH=arm-linux-androideabi
ARCH=arm
CPU=armv7-a
OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=neon -marm -march=$CPU -mtune=cortex-a8 -mthumb -D__thumb__ "
PREFIX=$(pwd)/ffmpeg-build/armeabi-v7a-neon
OUT_LIBRARY=../ffmpeg-build/armeabi-v7a/libffmpeg-neon.so
ADDITIONAL_CONFIGURE_FLAG=--enable-neon
SONAME=libffmpeg-neon.so
PREBUILT=$ANDROID_NDK_HOME/toolchains/arm-linux-androideabi-$COMPILATOR_VERSION/prebuilt/$OS_ARCH
PLATFORM_VERSION=android-9
setup_paths
build_x264
build_amr
build_aac
build_fribidi
build_freetype2
build_ass
build_ffmpeg
build_one
echo "BUILD SUCCESS"I’ve disabled the non-arm architectures for the time being. If there is any other information I can provide to help finding the problem, I will be happy to do so.
I’m wondering if the issue may be caused by something missing in the script, namely in build_one part, tho I tried to indicate the libx264.a directly in —extra-ldflags, without success.
-
How to play and seek fragmented MP4 audio using MSE SourceBuffer ?
29 juin 2024, par Stefan FalkNote :




If you end up here, you might want to take a look at shaka-player and the accompanying shaka-streamer. Use it. Don't implement this yourself unless you really have to.




I am trying for quite some time now to be able to play an audio track on Chrome, Firefox, Safari, etc. but I keep hitting brick walls. My problem is currently that I am just not able to seek within a fragmented MP4 (or MP3).


At the moment I am converting audio files such as MP3 to fragmented MP4 (fMP4) and send them chunk-wise to the client. What I do is defining a
CHUNK_DURACTION_SEC
(chunk duration in seconds) and compute a chunk size like this :

chunksTotal = Math.ceil(this.track.duration / CHUNK_DURATION_SEC);
chunkSize = Math.ceil(this.track.fileSize / this.chunksTotal);



With this I partition the audio file and can fetch it entirely jumping
chunkSize
-many bytes for each chunk :

-----------------------------------------
| chunk 1 | chunk 2 | ... | chunk n |
-----------------------------------------



How audio files are converted to fMP4


ffmpeg -i input.mp3 -acodec aac -b:a 256k -f mp4 \
 -movflags faststart+frag_every_frame+empty_moov+default_base_moof \
 output.mp4



This seems to work with Chrome and Firefox (so far).


How chunks are appended


After following this example, and realizing that it's simply not working as it is explained here, I threw it away and started over from scratch. Unfortunately without success. It's still not working.


The following code is supposed to play a track from the very beginning to the very end. However, I also need to be able to seek. So far, this is simply not working. Seeking will just stop the audio after the
seeking
event got triggered.

The code


/* Desired chunk duration in seconds. */
const CHUNK_DURATION_SEC = 20;

const AUDIO_EVENTS = [
 'ended',
 'error',
 'play',
 'playing',
 'seeking',
 'seeked',
 'pause',
 'timeupdate',
 'canplay',
 'loadedmetadata',
 'loadstart',
 'updateend',
];


class ChunksLoader {

 /** The total number of chunks for the track. */
 public readonly chunksTotal: number;

 /** The length of one chunk in bytes */
 public readonly chunkSize: number;

 /** Keeps track of requested chunks. */
 private readonly requested: boolean[];

 /** URL of endpoint for fetching audio chunks. */
 private readonly url: string;

 constructor(
 private track: Track,
 private sourceBuffer: SourceBuffer,
 private logger: NGXLogger,
 ) {

 this.chunksTotal = Math.ceil(this.track.duration / CHUNK_DURATION_SEC);
 this.chunkSize = Math.ceil(this.track.fileSize / this.chunksTotal);

 this.requested = [];
 for (let i = 0; i < this.chunksTotal; i++) {
 this.requested[i] = false;
 }

 this.url = `${environment.apiBaseUrl}/api/tracks/${this.track.id}/play`;
 }

 /**
 * Fetch the first chunk.
 */
 public begin() {
 this.maybeFetchChunk(0);
 }

 /**
 * Handler for the "timeupdate" event. Checks if the next chunk should be fetched.
 *
 * @param currentTime
 * The current time of the track which is currently played.
 */
 public handleOnTimeUpdate(currentTime: number) {

 const nextChunkIndex = Math.floor(currentTime / CHUNK_DURATION_SEC) + 1;
 const hasAllChunks = this.requested.every(val => !!val);

 if (nextChunkIndex === (this.chunksTotal - 1) && hasAllChunks) {
 this.logger.debug('Last chunk. Calling mediaSource.endOfStream();');
 return;
 }

 if (this.requested[nextChunkIndex] === true) {
 return;
 }

 if (currentTime < CHUNK_DURATION_SEC * (nextChunkIndex - 1 + 0.25)) {
 return;
 }

 this.maybeFetchChunk(nextChunkIndex);
 }

 /**
 * Fetches the chunk if it hasn't been requested yet. After the request finished, the returned
 * chunk gets appended to the SourceBuffer-instance.
 *
 * @param chunkIndex
 * The chunk to fetch.
 */
 private maybeFetchChunk(chunkIndex: number) {

 const start = chunkIndex * this.chunkSize;
 const end = start + this.chunkSize - 1;

 if (this.requested[chunkIndex] == true) {
 return;
 }

 this.requested[chunkIndex] = true;

 if ((end - start) == 0) {
 this.logger.warn('Nothing to fetch.');
 return;
 }

 const totalKb = ((end - start) / 1000).toFixed(2);
 this.logger.debug(`Starting to fetch bytes ${start} to ${end} (total ${totalKb} kB). Chunk ${chunkIndex + 1} of ${this.chunksTotal}`);

 const xhr = new XMLHttpRequest();
 xhr.open('get', this.url);
 xhr.setRequestHeader('Authorization', `Bearer ${AuthenticationService.getJwtToken()}`);
 xhr.setRequestHeader('Range', 'bytes=' + start + '-' + end);
 xhr.responseType = 'arraybuffer';
 xhr.onload = () => {
 this.logger.debug(`Range ${start} to ${end} fetched`);
 this.logger.debug(`Requested size: ${end - start + 1}`);
 this.logger.debug(`Fetched size: ${xhr.response.byteLength}`);
 this.logger.debug('Appending chunk to SourceBuffer.');
 this.sourceBuffer.appendBuffer(xhr.response);
 };
 xhr.send();
 };

}

export enum StreamStatus {
 NOT_INITIALIZED,
 INITIALIZING,
 PLAYING,
 SEEKING,
 PAUSED,
 STOPPED,
 ERROR
}

export class PlayerState {
 status: StreamStatus = StreamStatus.NOT_INITIALIZED;
}


/**
 *
 */
@Injectable({
 providedIn: 'root'
})
export class MediaSourcePlayerService {

 public track: Track;

 private mediaSource: MediaSource;

 private sourceBuffer: SourceBuffer;

 private audioObj: HTMLAudioElement;

 private chunksLoader: ChunksLoader;

 private state: PlayerState = new PlayerState();

 private state$ = new BehaviorSubject<playerstate>(this.state);

 public stateChange = this.state$.asObservable();

 private currentTime$ = new BehaviorSubject<number>(null);

 public currentTimeChange = this.currentTime$.asObservable();

 constructor(
 private httpClient: HttpClient,
 private logger: NGXLogger
 ) {
 }

 get canPlay() {
 const state = this.state$.getValue();
 const status = state.status;
 return status == StreamStatus.PAUSED;
 }

 get canPause() {
 const state = this.state$.getValue();
 const status = state.status;
 return status == StreamStatus.PLAYING || status == StreamStatus.SEEKING;
 }

 public playTrack(track: Track) {
 this.logger.debug('playTrack');
 this.track = track;
 this.startPlayingFrom(0);
 }

 public play() {
 this.logger.debug('play()');
 this.audioObj.play().then();
 }

 public pause() {
 this.logger.debug('pause()');
 this.audioObj.pause();
 }

 public stop() {
 this.logger.debug('stop()');
 this.audioObj.pause();
 }

 public seek(seconds: number) {
 this.logger.debug('seek()');
 this.audioObj.currentTime = seconds;
 }

 private startPlayingFrom(seconds: number) {
 this.logger.info(`Start playing from ${seconds.toFixed(2)} seconds`);
 this.mediaSource = new MediaSource();
 this.mediaSource.addEventListener('sourceopen', this.onSourceOpen);

 this.audioObj = document.createElement('audio');
 this.addEvents(this.audioObj, AUDIO_EVENTS, this.handleEvent);
 this.audioObj.src = URL.createObjectURL(this.mediaSource);

 this.audioObj.play().then();
 }

 private onSourceOpen = () => {

 this.logger.debug('onSourceOpen');

 this.mediaSource.removeEventListener('sourceopen', this.onSourceOpen);
 this.mediaSource.duration = this.track.duration;

 this.sourceBuffer = this.mediaSource.addSourceBuffer('audio/mp4; codecs="mp4a.40.2"');
 // this.sourceBuffer = this.mediaSource.addSourceBuffer('audio/mpeg');

 this.chunksLoader = new ChunksLoader(
 this.track,
 this.sourceBuffer,
 this.logger
 );

 this.chunksLoader.begin();
 };

 private handleEvent = (e) => {

 const currentTime = this.audioObj.currentTime.toFixed(2);
 const totalDuration = this.track.duration.toFixed(2);
 this.logger.warn(`MediaSource event: ${e.type} (${currentTime} of ${totalDuration} sec)`);

 this.currentTime$.next(this.audioObj.currentTime);

 const currentStatus = this.state$.getValue();

 switch (e.type) {
 case 'playing':
 currentStatus.status = StreamStatus.PLAYING;
 this.state$.next(currentStatus);
 break;
 case 'pause':
 currentStatus.status = StreamStatus.PAUSED;
 this.state$.next(currentStatus);
 break;
 case 'timeupdate':
 this.chunksLoader.handleOnTimeUpdate(this.audioObj.currentTime);
 break;
 case 'seeking':
 currentStatus.status = StreamStatus.SEEKING;
 this.state$.next(currentStatus);
 if (this.mediaSource.readyState == 'open') {
 this.sourceBuffer.abort();
 }
 this.chunksLoader.handleOnTimeUpdate(this.audioObj.currentTime);
 break;
 }
 };

 private addEvents(obj, events, handler) {
 events.forEach(event => obj.addEventListener(event, handler));
 }

}
</number></playerstate>


Running it will give me the following output :






Apologies for the screenshot but it's not possible to just copy the output without all the stack traces in Chrome.




What I also tried was following this example and call
sourceBuffer.abort()
but that didn't work. It looks more like a hack that used to work years ago but it's still referenced in the docs (see "Example" -> "You can see something similar in action in Nick Desaulnier's bufferWhenNeeded demo ..").

case 'seeking':
 currentStatus.status = StreamStatus.SEEKING;
 this.state$.next(currentStatus); 
 if (this.mediaSource.readyState === 'open') {
 this.sourceBuffer.abort();
 } 
 break;



Trying with MP3


I have tested the above code under Chrome by converting tracks to MP3 :


ffmpeg -i input.mp3 -acodec aac -b:a 256k -f mp3 output.mp3



and creating a
SourceBuffer
usingaudio/mpeg
as type :

this.mediaSource.addSourceBuffer('audio/mpeg')



I have the same problem when seeking.


The issue wihout seeking


The above code has another issue :


After two minutes of playing, the audio playback starts to stutter and comes to a halt prematurely. So, the audio plays up to a point and then it stops without any obvious reason.


For whatever reason there is another
canplay
andplaying
event. A few seconds after, the audio simply stops..