
Recherche avancée
Médias (91)
-
#3 The Safest Place
16 octobre 2011, par
Mis à jour : Février 2013
Langue : English
Type : Audio
-
#4 Emo Creates
15 octobre 2011, par
Mis à jour : Février 2013
Langue : English
Type : Audio
-
#2 Typewriter Dance
15 octobre 2011, par
Mis à jour : Février 2013
Langue : English
Type : Audio
-
#1 The Wires
11 octobre 2011, par
Mis à jour : Février 2013
Langue : English
Type : Audio
-
ED-ME-5 1-DVD
11 octobre 2011, par
Mis à jour : Octobre 2011
Langue : English
Type : Audio
-
Revolution of Open-source and film making towards open film making
6 octobre 2011, par
Mis à jour : Juillet 2013
Langue : English
Type : Texte
Autres articles (80)
-
Le profil des utilisateurs
12 avril 2011, parChaque utilisateur dispose d’une page de profil lui permettant de modifier ses informations personnelle. Dans le menu de haut de page par défaut, un élément de menu est automatiquement créé à l’initialisation de MediaSPIP, visible uniquement si le visiteur est identifié sur le site.
L’utilisateur a accès à la modification de profil depuis sa page auteur, un lien dans la navigation "Modifier votre profil" est (...) -
Configurer la prise en compte des langues
15 novembre 2010, parAccéder à la configuration et ajouter des langues prises en compte
Afin de configurer la prise en compte de nouvelles langues, il est nécessaire de se rendre dans la partie "Administrer" du site.
De là, dans le menu de navigation, vous pouvez accéder à une partie "Gestion des langues" permettant d’activer la prise en compte de nouvelles langues.
Chaque nouvelle langue ajoutée reste désactivable tant qu’aucun objet n’est créé dans cette langue. Dans ce cas, elle devient grisée dans la configuration et (...) -
Personnaliser les catégories
21 juin 2013, parFormulaire de création d’une catégorie
Pour ceux qui connaissent bien SPIP, une catégorie peut être assimilée à une rubrique.
Dans le cas d’un document de type catégorie, les champs proposés par défaut sont : Texte
On peut modifier ce formulaire dans la partie :
Administration > Configuration des masques de formulaire.
Dans le cas d’un document de type média, les champs non affichés par défaut sont : Descriptif rapide
Par ailleurs, c’est dans cette partie configuration qu’on peut indiquer le (...)
Sur d’autres sites (13059)
-
FFmpeg unexpected behavior using -loop flag
7 décembre 2020, par all jazzDear hackers of the world !


I've been trying to use the beloved FFmpeg library to create a video from an image loop and audio using the famous Docker FFmpeg image, but it has been driving me crazy not producing the expected results (the results that I get when I run the ffmpeg command with the equivalent version on my Macbook).


Here is the command :


docker run -v $(pwd):$(pwd) -w $(pwd) jrottenberg/ffmpeg:4.3-alpine \
 -y \
 -stats \
 -loop 1 -i files/image.jpg \
 -i files/a.mp3 \
 -c:v libx265 -pix_fmt yuv420p10 \
 -c:a aac \
 -movflags +faststart \
 -shortest \
 -f mp4 test.mp4



It should create a test.mp4 with the provided audio and image that is ready to be uploaded to the unfortunate Youtube.


When I do this, the video seems to be lacking moov atoms (if I try to analyse it). Strangely enough, if I run this two times using the Docker image (overriding the same file), the video file will magically start to work.


I also tried using different ffmpeg os images and versions. It seems that ffmpeg docummentation and code repo could also benefit from some care and love.


What else I could do to get this fixed ?


Here is the output from the console :


-y \
 -stats \
 -loop 1 -i files/image.jpg \
 -i files/a.mp3 \
 -c:v libx265 -pix_fmt yuv420p10 \
 -c:a aac \
 -movflags +faststart \
 -shortest \
 -f mp4 test30.mp4
ffmpeg version 4.3.1 Copyright (c) 2000-2020 the FFmpeg developers
 built with gcc 6.4.0 (Alpine 6.4.0)
 configuration: --disable-debug --disable-doc --disable-ffplay --enable-shared --enable-avresample --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-gpl --enable-libass --enable-fontconfig --enable-libfreetype --enable-libvidstab --enable-libmp3lame --enable-libopus --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libxcb --enable-libx265 --enable-libxvid --enable-libx264 --enable-nonfree --enable-openssl --enable-libfdk_aac --enable-postproc --enable-small --enable-version3 --enable-libbluray --enable-libzmq --extra-libs=-ldl --prefix=/opt/ffmpeg --enable-libopenjpeg --enable-libkvazaar --enable-libaom --extra-libs=-lpthread --enable-libsrt --enable-libaribb24 --extra-cflags=-I/opt/ffmpeg/include --extra-ldflags=-L/opt/ffmpeg/lib
 libavutil 56. 51.100 / 56. 51.100
 libavcodec 58. 91.100 / 58. 91.100
 libavformat 58. 45.100 / 58. 45.100
 libavdevice 58. 10.100 / 58. 10.100
 libavfilter 7. 85.100 / 7. 85.100
 libavresample 4. 0. 0 / 4. 0. 0
 libswscale 5. 7.100 / 5. 7.100
 libswresample 3. 7.100 / 3. 7.100
 libpostproc 55. 7.100 / 55. 7.100
Input #0, image2, from 'files/image.jpg':
 Duration: 00:00:00.04, start: 0.000000, bitrate: 34300 kb/s
 Stream #0:0: Video: mjpeg, gray(bt470bg/unknown/unknown), 500x500 [SAR 240:240 DAR 1:1], 25 fps, 25 tbr, 25 tbn, 25 tbc
Input #1, mp3, from 'files/a.mp3':
 Metadata:
 title : Visions
 artist : Hattori Hanzo
 album : Visions
 encoded_by : Fission
 encoder : Lavf58.45.100
 TLEN : 16039
 track : 1
 Duration: 00:00:16.04, start: 0.000000, bitrate: 199 kb/s
 Stream #1:0: Audio: mp3, 44100 Hz, stereo, fltp, 191 kb/s
 Stream #1:1: Video: mjpeg, yuvj444p(pc, bt470bg/unknown/unknown), 500x500 [SAR 300:300 DAR 1:1], 90k tbr, 90k tbn, 90k tbc (attached pic)
 Metadata:
 comment : Other
Stream mapping:
 Stream #0:0 -> #0:0 (mjpeg (native) -> hevc (libx265))
 Stream #1:0 -> #0:1 (mp3 (mp3float) -> aac (native))
Press [q] to stop, [?] for help
x265 [info]: HEVC encoder version 3.1.1+1-04b37fdfd2dc
x265 [info]: build info [Linux][GCC 6.4.0][64 bit] 10bit
x265 [info]: using cpu capabilities: MMX2 SSE2Fast LZCNT SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2
x265 [info]: Main 10 profile, Level-3 (Main tier)
x265 [info]: Thread pool created using 8 threads
x265 [info]: Slices : 1
x265 [info]: frame threads / pool features : 3 / wpp(8 rows)
x265 [warning]: Source height < 720p; disabling lookahead-slices
x265 [info]: Coding QT: max CU size, min CU size : 64 / 8
x265 [info]: Residual QT: max TU size, max depth : 32 / 1 inter / 1 intra
x265 [info]: ME / range / subpel / merge : hex / 57 / 2 / 3
x265 [info]: Keyframe min / max / scenecut / bias: 25 / 250 / 40 / 5.00
x265 [info]: Lookahead / bframes / badapt : 20 / 4 / 2
x265 [info]: b-pyramid / weightp / weightb : 1 / 1 / 0
x265 [info]: References / ref-limit cu / depth : 3 / off / on
x265 [info]: AQ: mode / str / qg-size / cu-tree : 2 / 1.0 / 32 / 1
x265 [info]: Rate Control / qCompress : CRF-28.0 / 0.60
x265 [info]: tools: rd=3 psy-rd=2.00 early-skip rskip signhide tmvp b-intra
x265 [info]: tools: strong-intra-smoothing deblock sao
Output #0, mp4, to 'test30.mp4':
 Metadata:
 encoder : Lavf58.45.100
 Stream #0:0: Video: hevc (libx265) (hev1 / 0x31766568), yuv420p10le(progressive), 500x500 [SAR 1:1 DAR 1:1], q=-1--1, 25 fps, 12800 tbn, 25 tbc
 Metadata:
 encoder : Lavc58.91.100 libx265
 Side data:
 cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A
 Stream #0:1: Audio: aac (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 128 kb/s
 Metadata:
 encoder : Lavc58.91.100 aac
frame= 52 fps=0.0 q=33.0 size= 0kB time=00:00:00.80 bitrate= 0.4kbits/frame= 120 fps=119 q=33.0 size= 0kB time=00:00:03.52 bitrate= 0.1kbits/frame= 190 fps=125 q=33.0 size= 0kB time=00:00:06.33 bitrate= 0.1kbits/frame= 257 fps=127 q=33.0 size= 0kB time=00:00:09.00 bitrate= 0.0kbits/frame= 303 fps=120 q=35.0 size= 256kB time=00:00:10.86 bitrate= 193.0kbits/frame= 373 fps=123 q=36.0 size= 256kB time=00:00:13.65 bitrate= 153.6kbits/[mp4 @ 0x55d481bc6980] Starting second pass: moving the moov atom to the beginning of the file
frame= 432 fps=121 q=36.0 Lsize= 379kB time=00:00:17.16 bitrate= 180.8kbits/s speed= 4.8x
video:107kB audio:255kB subtitle:0kB other streams:0kB global headers:2kB muxing overhead: 4.667185%
x265 [info]: frame I: 2, Avg QP:23.55 kb/s: 8634.80
x265 [info]: frame P: 147, Avg QP:33.00 kb/s: 13.49
x265 [info]: frame B: 283, Avg QP:35.71 kb/s: 8.06
x265 [info]: Weighted P-Frames: Y:0.0% UV:0.0%
x265 [info]: consecutive B-frames: 34.2% 10.1% 20.8% 1.3% 33.6%

encoded 432 frames in 3.56s (121.32 fps), 49.84 kb/s, Avg QP:34.73
[aac @ 0x55d481b23ac0] Qavg: 563.168```



-
ffmpeg undefined reference to sws_getContext
23 septembre 2021, par Wenfei ZhuI am learning to use ffmpeg libraries, and have successfully compiled and run a program that demuxes and decodes a video. However, when I was trying to use the swscale library, I got a linking error "undefined reference to sws_getContext". There are similar problems on the Internet but none of them solves my problem.


The full error message is


/usr/bin/ld: CMakeFiles/ffmpeg_test.dir/main.cpp.o: in function `main':
main.cpp:(.text+0x44f): undefined reference to `sws_getContext'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/ffmpeg_test.dir/build.make:93: ffmpeg_test] Error 1
make[1]: *** [CMakeFiles/Makefile2:76: CMakeFiles/ffmpeg_test.dir/all] Error 2
make: *** [Makefile:84: all] Error 2



Here is my Dockerfile, source file and CMakeList.


# FFMPEG Image
# ref:https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu

FROM ubuntu:20.04

ARG http_proxy=''
ARG https_proxy=''
ENV HTTP_PROXY=${http_proxy}
ENV HTTPS_PROXY=${https_proxy}

RUN apt-get update \
 && DEBIAN_FRONTEND="noninteractive" \
 apt-get install -y --no-install-recommends \
 autoconf \
 automake \
 build-essential \
 cmake \
 git \
 libass-dev \
 libfreetype6-dev \
 libgnutls28-dev \
 # libsdl2-dev \
 libtool \
 # libva-dev \
 # libvdpau-dev \
 libvorbis-dev \
 # libxcb1-dev \
 # libxcb-shm0-dev \
 # libxcb-xfixes0-dev \
 meson \
 ninja-build \
 pkg-config \
 texinfo \
 wget \
 yasm \
 zlib1g-dev \
 libunistring-dev \
 python3.8-dev \
 ca-certificates

ARG FFMPEG_ROOT=/root/ffmpeg
RUN mkdir ${FFMPEG_ROOT}
WORKDIR ${FFMPEG_ROOT}

RUN mkdir sources && mkdir build && mkdir bin

# NASM
RUN cd sources \
 && wget https://www.nasm.us/pub/nasm/releasebuilds/2.15.05/nasm-2.15.05.tar.bz2 \
 && tar xjvf nasm-2.15.05.tar.bz2 \
 && cd nasm-2.15.05 \
 && ./autogen.sh \
 && PATH="${FFMPEG_ROOT}/bin:$PATH" \
 ./configure \
 --prefix="${FFMPEG_ROOT}/build" \
 --bindir="${FFMPEG_ROOT}/bin" \
 --enable-shared \
 --enable-pic \
 && make -j$(nproc) \
 && make install

# H.264 video encoder (GPL License!!! --enable-gpl --enable-libx264)
RUN cd sources \
 && git -C x264 pull 2> /dev/null || git clone --depth 1 https://code.videolan.org/videolan/x264.git \
 && cd x264 \
 && PATH="${FFMPEG_ROOT}/bin:$PATH" \
 PKG_CONFIG_PATH="${FFMPEG_ROOT}/build/lib/pkgconfig" \
 ./configure \
 --prefix="${FFMPEG_ROOT}/build" \
 --bindir="${FFMPEG_ROOT}/bin" \
 --enable-shared \
 --enable-pic \
 --disable-cli \
 && PATH="${FFMPEG_ROOT}/bin:$PATH" make -j$(nproc) \
 && make install

# H.265/HEVC video encoder (GPL License!!! --enable-gpl --enable-libx265)
RUN apt-get install -y --no-install-recommends libnuma-dev \
 && cd sources \
 && git -C x265_git pull 2> /dev/null || git clone https://bitbucket.org/multicoreware/x265_git \
 && cd x265_git/build/linux \
 && PATH="${FFMPEG_ROOT}/bin:$PATH" \
 cmake \
 -G "Unix Makefiles" \
 -DCMAKE_INSTALL_PREFIX="${FFMPEG_ROOT}/build" \
 -DENABLE_SHARED=on \
 -DENABLE_CLI=off \
 ../../source \
 && PATH="${FFMPEG_ROOT}/bin:$PATH" make -j$(nproc) \
 && make install

# VP8/VP9 video encoder/decoder (--enable-libvpx)
RUN cd sources \
 && git -C libvpx pull 2> /dev/null || git clone --depth 1 https://chromium.googlesource.com/webm/libvpx.git \
 && cd libvpx \
 && PATH="${FFMPEG_ROOT}/bin:$PATH" \
 ./configure \
 --prefix="${FFMPEG_ROOT}/build" \
 --disable-debug \
 --disable-examples \
 --disable-docs \
 --disable-unit-tests \
 --enable-vp9-highbitdepth \
 --as=yasm \
 --enable-pic \
 --enable-shared \
 && PATH="${FFMPEG_ROOT}/bin:$PATH" make -j$(nproc) \
 && make install

# # AAC audio encoder (NON-FREE!!! --enable-gpl --enable-nonfree --enable-libfdk-aac)
# RUN cd sources \
# && git -C fdk-aac pull 2> /dev/null || git clone --depth 1 https://github.com/mstorsjo/fdk-aac \
# && cd fdk-aac \
# && autoreconf -fiv \
# && ./configure \
# --prefix="${FFMPEG_ROOT}/build" \
# --disable-shared \
# && make -j$(nproc) \
# && make install

# MP3 audio encoder (--enable-libmp3lame)
RUN cd sources \
 && wget -O lame-3.100.tar.gz https://downloads.sourceforge.net/project/lame/lame/3.100/lame-3.100.tar.gz \
 && tar xzvf lame-3.100.tar.gz \
 && cd lame-3.100 \
 && PATH="${FFMPEG_ROOT}/bin:$PATH" \
 ./configure \
 --prefix="${FFMPEG_ROOT}/build" \
 --bindir="${FFMPEG_ROOT}/bin" \
 --enable-shared \
 --enable-pic \
 --enable-nasm \
 && PATH="${FFMPEG_ROOT}/bin:$PATH" make -j$(nproc) \
 && make install

# Opus audio decoder and encoder (--enable-libopus)
RUN cd sources \
 && git -C opus pull 2> /dev/null || git clone --depth 1 https://github.com/xiph/opus.git \
 && cd opus \
 && ./autogen.sh \
 && ./configure \
 --prefix="${FFMPEG_ROOT}/build" \
 --enable-shared \
 && make -j$(nproc) \
 && make install

# AV1 video encoder/decoder
# encoder (--enable-libsvtav1)
RUN cd sources \
 && git -C SVT-AV1 pull 2> /dev/null || git clone https://gitlab.com/AOMediaCodec/SVT-AV1.git \
 && mkdir -p SVT-AV1/build \
 && cd SVT-AV1/build \
 && PATH="${FFMPEG_ROOT}/bin:$PATH" \
 cmake \
 -G "Unix Makefiles" \
 -DCMAKE_INSTALL_PREFIX="${FFMPEG_ROOT}/build" \
 -DCMAKE_BUILD_TYPE=Release \
 -DBUILD_DEC=OFF \
 -DBUILD_SHARED_LIBS=ON \
 .. \
 && PATH="${FFMPEG_ROOT}/bin:$PATH" make -j$(nproc)\
 && make install
# decoder (--enable-libdav1d)
RUN cd sources \
 && git -C dav1d pull 2> /dev/null || git clone --depth 1 https://code.videolan.org/videolan/dav1d.git \
 && mkdir -p dav1d/build \
 && cd dav1d/build \
 && PATH="${FFMPEG_ROOT}/bin:$PATH" \
 meson setup \
 -Denable_tools=false \
 -Denable_tests=false \
 --default-library=shared \
 .. \
 --prefix="${FFMPEG_ROOT}/build" \
 --libdir="${FFMPEG_ROOT}/build/lib" \
 && ninja -j$(nproc) \
 && ninja install

# Library for calculating the VMAF video quality metric (--enable-libvmaf --ld="g++")
RUN cd sources \
 && wget https://github.com/Netflix/vmaf/archive/v2.1.1.tar.gz \
 && tar xvf v2.1.1.tar.gz \
 && mkdir -p vmaf-2.1.1/libvmaf/build \
 && cd vmaf-2.1.1/libvmaf/build \
 && PATH="${FFMPEG_ROOT}/bin:$PATH" \
 meson setup \
 -Denable_tests=false \
 -Denable_docs=false \
 --buildtype=release \
 --default-library=shared \
 .. \
 --prefix "${FFMPEG_ROOT}/build" \
 --bindir="${FFMPEG_ROOT}/build/bin" \
 --libdir="${FFMPEG_ROOT}/build/lib" \
 && ninja -j$(nproc) \
 && ninja install

# FFMPEG
RUN cd sources \
 && wget -O ffmpeg-snapshot.tar.bz2 https://ffmpeg.org/releases/ffmpeg-snapshot.tar.bz2 \
 && tar xjvf ffmpeg-snapshot.tar.bz2 \
 && cd ffmpeg \
 && PATH="${FFMPEG_ROOT}/bin:$PATH" \
 PKG_CONFIG_PATH="${FFMPEG_ROOT}/build/lib/pkgconfig" \
 ./configure \
 --prefix="${FFMPEG_ROOT}/build" \
 --pkg-config-flags="--static" \
 --extra-cflags="-I${FFMPEG_ROOT}/build/include" \
 --extra-ldflags="-L${FFMPEG_ROOT}/build/lib" \
 --extra-libs="-lpthread -lm" \
 --ld="g++" \
 --bindir="${FFMPEG_ROOT}/bin" \
 --disable-debug \
 --disable-doc \
 --disable-ffplay \
 --enable-shared \
 --enable-pic \
 --enable-gpl \
 --enable-gnutls \
 # --enable-libaom \
 --enable-libass \
 # --enable-libfdk-aac \
 --enable-libfreetype \
 --enable-libmp3lame \
 --enable-libopus \
 --enable-libsvtav1 \
 --enable-libdav1d \
 --enable-libvorbis \
 --enable-libvpx \
 --enable-libx264 \
 --enable-libx265 \
 # --enable-nonfree \
 && PATH="${FFMPEG_ROOT}/bin:$PATH" make -j$(nproc) \
 && make install \
 && hash -r

# opencv
RUN apt-get update \
 & apt-get install -y --no-install-recommends libopencv-dev




#include <iostream>

extern "C" {
#include <libavutil></libavutil>avutil.h>
#include <libavcodec></libavcodec>avcodec.h>
#include <libavformat></libavformat>avformat.h>
#include <libswscale></libswscale>swscale.h>
}

#include <opencv2></opencv2>core.hpp>

// fix c++ av_err2str problem
// ref: https://github.com/joncampbell123/composite-video-simulator/issues/5
#ifdef av_err2str
#undef av_err2str
#include <string>
av_always_inline std::string av_err2string(int errnum) {
 char str[AV_ERROR_MAX_STRING_SIZE];
 return av_make_error_string(str, AV_ERROR_MAX_STRING_SIZE, errnum);
}
#define av_err2str(err) av_err2string(err).c_str()
#endif // av_err2str


static int decode_packet(AVPacket *, AVCodecContext *, AVFrame *, AVStream *);


int main(int argc, const char *argv[]) {
 std::cout << "hello world" << std::endl;
 AVFormatContext *pFormatContext = avformat_alloc_context();

 if (avformat_open_input(&pFormatContext, argv[1], NULL, NULL) != 0) {
 std::cout << "ERROR could not open the file\n";
 return -1;
 }

 printf("File format %s, duration %.2fs, bit_rate %ld\n", pFormatContext->iformat->long_name, pFormatContext->duration / 1e6, pFormatContext->bit_rate);

 if (avformat_find_stream_info(pFormatContext, NULL) < 0) {
 std::cout << "ERROR could not get the stream info\n";
 return -1;
 }

 int video_stream_index = -1;

 printf("Number of streams %d\n", pFormatContext->nb_streams);

 AVCodecParameters *pVideoCodecParameters;
 const AVCodec *pVideoCodec;
 AVStream *pVideoStream;

 for (int i = 0; i < pFormatContext->nb_streams; i++)
 {
 AVCodecParameters *pLocalCodecParameters = pFormatContext->streams[i]->codecpar;
 const AVCodec *pLocalCodec = NULL;
 pLocalCodec = avcodec_find_decoder(pLocalCodecParameters->codec_id);

 // print its name and bitrate
 printf("Codec %s, bit_rate %ld\n", pLocalCodec->long_name, pLocalCodecParameters->bit_rate);

 if (pLocalCodecParameters->codec_type == AVMEDIA_TYPE_VIDEO) {
 if (video_stream_index == -1) {
 video_stream_index = i;
 pVideoCodecParameters = pLocalCodecParameters;
 pVideoCodec = pLocalCodec;
 }
 pVideoStream = pFormatContext->streams[i];
 AVRational *fps = &pVideoStream->avg_frame_rate;
 AVRational *rfps = &pVideoStream->r_frame_rate;
 AVRational *time_base = &pVideoStream->time_base;
 printf("Video Codec: resolution %d x %d, fps %d/%d, frames %ld, time base %d/%d, rfps %d/%d\n", 
 pLocalCodecParameters->width, pLocalCodecParameters->height, 
 fps->num, fps->den, pVideoStream->nb_frames, time_base->num, time_base->den,
 rfps->num, rfps->den);
 } else if (pLocalCodecParameters->codec_type == AVMEDIA_TYPE_AUDIO) {
 printf("Audio Codec: %d channels, sample rate %d\n", pLocalCodecParameters->channels, pLocalCodecParameters->sample_rate);
 }
 
 if (pLocalCodec==NULL) {
 printf("ERROR unsupported codec!\n");
 // In this example if the codec is not found we just skip it
 continue;
 }
 }

 if (video_stream_index == -1) {
 printf("File %s does not contain a video stream!\n", argv[1]);
 return -1;
 }

 AVCodecContext *pCodecContext = avcodec_alloc_context3(pVideoCodec);
 if (!pCodecContext)
 {
 printf("failed to allocated memory for AVCodecContext\n");
 return -1;
 }

 if (avcodec_parameters_to_context(pCodecContext, pVideoCodecParameters) < 0)
 {
 printf("failed to copy codec params to codec context\n");
 return -1;
 }

 if (avcodec_open2(pCodecContext, pVideoCodec, NULL) < 0)
 {
 printf("failed to open codec through avcodec_open2\n");
 return -1;
 }

 // https://ffmpeg.org/doxygen/trunk/structAVPacket.html
 AVPacket *pPacket = av_packet_alloc();
 if (!pPacket)
 {
 printf("failed to allocated memory for AVPacket\n");
 return -1;
 }
 
 // https://ffmpeg.org/doxygen/trunk/structAVFrame.html
 AVFrame *pFrame = av_frame_alloc();
 if (!pFrame)
 {
 printf("failed to allocated memory for AVFrame\n");
 return -1;
 }

 SwsContext *pImgConvertContext = sws_getContext(
 pCodecContext->width,
 pCodecContext->height,
 pCodecContext->pix_fmt,
 pCodecContext->width,
 pCodecContext->height,
 AV_PIX_FMT_BGR24,
 SWS_BICUBIC,
 NULL,
 NULL,
 NULL
 );

 int response = 0;
 int how_many_packets_to_process = 8;

 // fill the Packet with data from the Stream
 // https://ffmpeg.org/doxygen/trunk/group__lavf__decoding.html#ga4fdb3084415a82e3810de6ee60e46a61
 while (av_read_frame(pFormatContext, pPacket) >= 0)
 {
 // if it's the video stream
 if (pPacket->stream_index == video_stream_index) {
 printf("AVPacket->pts %" PRId64, pPacket->pts);
 std::cout << std::endl;
 response = decode_packet(pPacket, pCodecContext, pFrame, pVideoStream);
 if (response < 0)
 break;
 // stop it, otherwise we'll be saving hundreds of frames
 if (--how_many_packets_to_process <= 0) break;
 }
 // https://ffmpeg.org/doxygen/trunk/group__lavc__packet.html#ga63d5a489b419bd5d45cfd09091cbcbc2
 av_packet_unref(pPacket);
 }

 avformat_close_input(&pFormatContext);
 av_packet_free(&pPacket);
 av_frame_free(&pFrame);
 avcodec_free_context(&pCodecContext);

 std::cout << "bye world" << std::endl;
 return 0;
}

static int decode_packet(AVPacket *pPacket, AVCodecContext *pCodecContext, AVFrame *pFrame, AVStream *pStream)
{
 // Supply raw packet data as input to a decoder
 // https://ffmpeg.org/doxygen/trunk/group__lavc__decoding.html#ga58bc4bf1e0ac59e27362597e467efff3
 int response = avcodec_send_packet(pCodecContext, pPacket);
 // printf("response %d\n", response);

 if (response < 0) {
 printf("Error while sending a packet to the decoder: %s\n", av_err2str(response));
 return response;
 }

 while (response >= 0)
 {
 // Return decoded output data (into a frame) from a decoder
 // https://ffmpeg.org/doxygen/trunk/group__lavc__decoding.html#ga11e6542c4e66d3028668788a1a74217c
 response = avcodec_receive_frame(pCodecContext, pFrame);
 if (response == AVERROR(EAGAIN) || response == AVERROR_EOF) {
 break;
 } else if (response < 0) {
 printf("Error while receiving a frame from the decoder: %s\n", av_err2str(response));
 return response;
 }

 if (response >= 0) {
 float time_base = pStream->time_base.num / float(pStream->time_base.den);
 printf(
 "Frame %d (type=%c, size=%d bytes, format=%d) pts %ld timestampe %.2f key_frame %d [DTS %d]\n",
 pCodecContext->frame_number,
 av_get_picture_type_char(pFrame->pict_type),
 pFrame->pkt_size,
 pFrame->format,
 pFrame->pts,
 pFrame->pts * time_base,
 pFrame->key_frame,
 pFrame->coded_picture_number
 );

 // char frame_filename[1024];
 // snprintf(frame_filename, sizeof(frame_filename), "%s-%d.pgm", "frame", pCodecContext->frame_number);
 // Check if the frame is a planar YUV 4:2:0, 12bpp
 // That is the format of the provided .mp4 file
 // RGB formats will definitely not give a gray image
 // Other YUV image may do so, but untested, so give a warning
 // if (pFrame->format != AV_PIX_FMT_YUV420P)
 // {
 // printf("Warning: the generated file may not be a grayscale image, but could e.g. be just the R component if the video format is RGB");
 // }
 // save a grayscale frame into a .pgm file
 // save_gray_frame(pFrame->data[0], pFrame->linesize[0], pFrame->width, pFrame->height, frame_filename);
 }
 }
 return 0;
}
</string></iostream>


cmake_minimum_required(VERSION 3.10)

# set the project name
project(ffmpeg_test)

# specify the C++ standard
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)

# add the executable
add_executable(ffmpeg_test main.cpp)

# link ffmpeg
set(FFMPEG_ROOT "/root/ffmpeg/build")

target_include_directories(ffmpeg_test PUBLIC "${FFMPEG_ROOT}/include")
target_link_libraries(ffmpeg_test 
 "${FFMPEG_ROOT}/lib/libavutil.so"
 "${FFMPEG_ROOT}/lib/libpostproc.so"
 "${FFMPEG_ROOT}/lib/libswresample.so"
 "${FFMPEG_ROOT}/lib/libswscale.so"
 "${FFMPEG_ROOT}/lib/libavfilter.so"
 "${FFMPEG_ROOT}/lib/libavdevice.so"
 "${FFMPEG_ROOT}/lib/libavformat.so"
 "${FFMPEG_ROOT}/lib/libavcodec.so"
)

# link opencv
target_include_directories(ffmpeg_test PUBLIC "/usr/include/opencv4")
target_link_libraries(ffmpeg_test 
 "/usr/lib/x86_64-linux-gnu/libopencv_core.so"
)
# find_library(OpenCV REQUIRED)
# message(STATUS ${OpenCV_VERSION})
# message(STATUS ${OpenCV_LIBS})
# message(STATUS ${OpenCV_INCLUDE_DIRS})




-
fail continuous transfer video file into buffer
9 décembre 2016, par chintitomasudhere I want to process a video file transcoding on demand by using ffmpeg but I failed. without ffmpeg all code runs properly. but using ffmpeg I face some problem. it shows this message :
Spawning new process /samiul113039/1080.mp4:GET piping ffmpeg output to client, pid 10016 HTTP connection disrupted, killing ffmpeg : 10016 Spawning new process /samiul113039/1080.mp4:GET piping ffmpeg output to client, pid 4796 HTTP connection disrupted, killing ffmpeg : 4796 ffmpeg didn’t quit on q, sending signals ffmpeg has exited : 10016, code null ffmpeg didn’t quit on q, sending signals ffmpeg has exited : 4796, code nul
var fs=require('fs');
var url=require("url");
var urlvalue="http://csestudents.uiu.ac.bd/samiul113039/1080.mp4";
var parseurl=url.parse(urlvalue);
var HDHomeRunIP = parseurl.hostname;
var HDHomeRunPort = parseurl.port;
var childKillTimeoutMs = 1000;
var parseArgs = require('minimist')(process.argv.slice(2));
// define startsWith for string
if (typeof String.prototype.startsWith != 'function') {
// see below for better implementation!
String.prototype.startsWith = function (str){
return this.indexOf(str) == 0;
};
}
// Called when the response object fires the 'close' handler, kills ffmpeg
function responseCloseHandler(command) {
if (command.exited != true) {
console.log('HTTP connection disrupted, killing ffmpeg: ' + command.pid);
// Send a 'q' which signals ffmpeg to quit.
// Then wait half a second, send a nice signal, wait another half second
// and send SIGKILL
command.stdin.write('q\n');
command.stdin.destroy();
// install timeout and wait
setTimeout(function() {
if (command.exited != true) {
console.log('ffmpeg didn\'t quit on q, sending signals');
// still connected, do safe sig kills
command.kill();
try {
command.kill('SIGQUIT');
} catch (err) {}
try {
command.kill('SIGINT');
} catch (err) {}
// wait some more!
setTimeout(function() {
if (command.exited != true) {
console.log('ffmpeg didn\'t quit on signals, sending SIGKILL');
// at this point, just give up and whack it
try {
command.kill('SIGKILL');
} catch (err) {}
}
}, childKillTimeoutMs);
}
}, childKillTimeoutMs);
}
}
// Performs a proxy. Copies data from proxy_request into response
function doProxy(request,response,http,options) {
var proxy_request = http.request(options, function (proxy_response) {
proxy_response.on('data', function(chunk) {
response.write(chunk, 'binary');
});
proxy_response.on('end', function() {
response.end();
});
response.writeHead(proxy_response.statusCode, proxy_response.headers);
});
request.on('data', function(chunk) {
proxy_request.write(chunk, 'binary');
});
// error handler
proxy_request.on('error', function(e) {
console.log('problem with request: ' + e.message);
response.writeHeader(500);
response.end();
});
proxy_request.end();
}
var child_process = require('child_process');
var auth = require('./auth');
// Performs the transcoding after the URL is validated
function doTranscode(request,response) {
//res.setHeader("Accept-Ranges", "bytes");
response.setHeader("Accept-Ranges", "bytes");
response.setHeader("Content-Type", "video/mp4");
response.setHeader("Connection","close");
response.setHeader("Cache-Control","no-cache");
response.setHeader("Pragma","no-cache");
// always write the header
response.writeHeader(200);
// if get, spawn command stream it
if (request.method == 'GET') {
console.log('Spawning new process ' + request.url + ":" + request.method);
var command = child_process.spawn('ffmpeg',
['-i','http://csestudents.uiu.ac.bd/samiul113039/1080.mp4','-f','mpegts','-'],
{ stdio: ['pipe','pipe','ignore'] });
command.exited = false;
// handler for when ffmpeg dies unexpectedly
command.on('exit',function(code,signal) {
console.log('ffmpeg has exited: ' + command.pid + ", code " + code);
// set flag saying we've quit
command.exited = true;
response.end();
});
command.on('error',function(error) {
console.log('ffmpeg error handler - unable to kill: ' + command.pid);
// on well, might as well give up
command.exited = true;
try {
command.stdin.close();
} catch (err) {}
try {
command.stdout.close();
} catch (err) {}
try {
command.stderr.close();
} catch (err) {}
response.end();
});
// handler for when client closes the URL connection - stop ffmpeg
response.on('end',function() {
responseCloseHandler(command);
});
// handler for when client closes the URL connection - stop ffmpeg
response.on('close',function() {
responseCloseHandler(command);
});
// now stream
console.log('piping ffmpeg output to client, pid ' + command.pid);
command.stdout.pipe(response);
command.stdin.on('error',function(err) {
console.log("Weird error in stdin pipe ", err);
response.end();
});
command.stdout.on('error',function(err) {
console.log("Weird error in stdout pipe ",err);
response.end();
});
}
else {
// not GET, so close response
response.end();
}
}
// Load the http module to create an http server.
var http = require('http');
// Configure our HTTP server to respond with Hello World to all requests.
var server = http.createServer(function (request, response) {
//console.log("New connection from " + request.socket.remoteAddress + ":" + request.url);
if (auth.validate(request,response)) {
// first send a HEAD request to our HD Home Run with the same url to see if the address is valid.
// This prevents an ffmpeg instance to spawn when clients request invalid things - like robots.txt/etc
var options = {method: 'HEAD', hostname: HDHomeRunIP, port: HDHomeRunPort, path: request.url};
var req = http.request(options, function(res) {
// if they do a get, and it returns good status
if (request.method == "GET" &&
res.statusCode == 200 &&
res.headers["content-type"] != null &&
res.headers["content-type"].startsWith("video")) {
// transcode is possible, start it now!
doTranscode(request,response);
}
else {
// no video or error, cannot transcode, just forward the response from the HD Home run to the client
if (request.method == "HEAD") {
response.writeHead(res.statusCode,res.headers);
response.end();
}
else {
// do a 301 redirect and have the device response directly
// just proxy it, that way browser doesn't redirect to HDHomeRun IP but keeps the node.js server IP
options = {method: request.method, hostname: HDHomeRunIP, /* port: HDHomeRunPort, */path: request.url};
doProxy(request,response,http,options);
}
}
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
response.writeHeader(500);
response.end();
});
// finish the client request, rest of processing done in the async callbacks
req.end();
}
});
// turn on no delay for tcp
server.on('connection', function (socket) {
socket.setNoDelay(true);
});
server.listen(7000);