
Recherche avancée
Autres articles (70)
-
Mise à jour de la version 0.1 vers 0.2
24 juin 2013, parExplications des différents changements notables lors du passage de la version 0.1 de MediaSPIP à la version 0.3. Quelles sont les nouveautés
Au niveau des dépendances logicielles Utilisation des dernières versions de FFMpeg (>= v1.2.1) ; Installation des dépendances pour Smush ; Installation de MediaInfo et FFprobe pour la récupération des métadonnées ; On n’utilise plus ffmpeg2theora ; On n’installe plus flvtool2 au profit de flvtool++ ; On n’installe plus ffmpeg-php qui n’est plus maintenu au (...) -
Personnaliser en ajoutant son logo, sa bannière ou son image de fond
5 septembre 2013, parCertains thèmes prennent en compte trois éléments de personnalisation : l’ajout d’un logo ; l’ajout d’une bannière l’ajout d’une image de fond ;
-
Ecrire une actualité
21 juin 2013, parPrésentez les changements dans votre MédiaSPIP ou les actualités de vos projets sur votre MédiaSPIP grâce à la rubrique actualités.
Dans le thème par défaut spipeo de MédiaSPIP, les actualités sont affichées en bas de la page principale sous les éditoriaux.
Vous pouvez personnaliser le formulaire de création d’une actualité.
Formulaire de création d’une actualité Dans le cas d’un document de type actualité, les champs proposés par défaut sont : Date de publication ( personnaliser la date de publication ) (...)
Sur d’autres sites (12425)
-
Add 2 pictures to video with durations ? [duplicate]
24 juin 2013, par jesperThis question already has an answer here :
I am trying to add 2 different images into a video with ffmpeg.
image1.jpg should show the first 10 seconds of the movie and youtubeLOL.png should show the next 6 minutes of the video.
So the command should tell us also to repeat the pictures to get a length for 6 minutes and 10 seconds. How can i do this ? I have tried this :
(It's not even working)
passthru("ffmpeg -f image2 -loop 1 -vframes 100 -i /home/psafari/public_html/youtube_images/movie_" . $id . ".jpg -vcodec mpeg4 /home/psafari/public_html/youtube_videos/movie_" . time().".avi");
Here is output :
FFmpeg version 0.6.5, Copyright (c) 2000-2010 the FFmpeg developers built on Jan 29 2012 17:52:15 with gcc 4.4.5 20110214 (Red Hat 4.4.5-6) configuration: --prefix=/usr --libdir=/usr/lib64 --shlibdir=/usr/lib64 --mandir=/usr/share/man --incdir=/usr/include --disable-avisynth --extra-cflags='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -fPIC' --enable-avfilter --enable-avfilter-lavf --enable-libdc1394 --enable-libdirac --enable-libfaac --enable-libfaad --enable-libfaadbin --enable-libgsm --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-librtmp --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-libx264 --enable-gpl --enable-nonfree --enable-postproc --enable-pthreads --enable-shared --enable-swscale --enable-vdpau --enable-version3 --enable-x11grab libavutil 50.15. 1 / 50.15. 1 libavcodec 52.72. 2 / 52.72. 2 libavformat 52.64. 2 / 52.64. 2 libavdevice 52. 2. 0 / 52. 2. 0 libavfilter 1.19. 0 / 1.19. 0 libswscale 0.11. 0 / 0.11. 0 libpostproc 51. 2. 0 / 51. 2. 0
Invalid value '1' for option 'loop'output memcode
MEncoder SVN-r31628-4.4.6 (C) 2000-2010 MPlayer Team
get_path("config") problem
success: format: 0 data: 0x0 - 0x1251b
libavformat file format detected.
[lavf] stream 0: video (h264), -vid 0
VIDEO: [H264] 540x800 24bpp 25.000 fps 116.3 kbps (14.2 kbyte/s)
[V] filefmt:44 fourcc:0x34363248 size:540x800 fps:25.000 ftime:=0.0400
videocodec: framecopy (540x800 24bpp fourcc=34363248)
Writing header...
ODML: Aspect information not (yet?) available or unspecified, not writing vprp header.
Writing header...
ODML: Aspect information not (yet?) available or unspecified, not writing vprp header.
Pos: 0.0s 1f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [0:0]
Pos: 0.1s 2f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [0:0]
Pos: 0.1s 3f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [0:0]
Pos: 0.2s 4f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [0:0]
Pos: 0.2s 5f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [0:0]
Pos: 0.2s 6f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [0:0]
Pos: 0.3s 7f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [0:0]
Pos: 0.3s 8f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [0:0]
Pos: 0.4s 9f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [0:0]
Pos: 0.4s 10f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [0:0]
Pos: 0.4s 11f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [0:0]
Pos: 0.5s 12f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [0:0]
Pos: 0.5s 13f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [0:0]
Pos: 0.6s 14f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [0:0]
Pos: 0.6s 15f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [0:0]
Pos: 0.6s 16f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [0:0]
Pos: 0.7s 17f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [0:0]
Pos: 0.7s 18f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [0:0]
Pos: 0.8s 19f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [0:0]
Pos: 0.8s 20f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [0:0]
Pos: 0.8s 21f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [0:0]
Pos: 0.9s 22f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [0:0]
Pos: 0.9s 23f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [0:0]
Pos: 1.0s 24f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [0:0]
Pos: 1.0s 25f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [0:0]
Pos: 1.0s 26f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [538:0]
Pos: 1.1s 27f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [518:0]
Pos: 1.1s 28f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [500:0]
Pos: 1.2s 29f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [483:0]
Pos: 1.2s 30f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [467:0]
Pos: 1.2s 31f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [452:0]
Pos: 1.3s 32f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [438:0]
Pos: 1.3s 33f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [425:0]
Pos: 1.4s 34f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [413:0]
Pos: 1.4s 35f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [401:0]
Pos: 1.4s 36f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [390:0]
Pos: 1.5s 37f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [380:0]
Pos: 1.5s 38f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [370:0]
Pos: 1.6s 39f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [360:0]
Pos: 1.6s 40f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [351:0]
Pos: 1.6s 41f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [343:0]
Pos: 1.7s 42f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [335:0]
Pos: 1.7s 43f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [327:0]
Pos: 1.8s 44f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [320:0]
Pos: 1.8s 45f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [313:0]
Pos: 1.8s 46f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [306:0]
Pos: 1.9s 47f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [300:0]
Pos: 1.9s 48f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [294:0]
Pos: 2.0s 49f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [288:0]
Pos: 2.0s 50f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [282:0]
Pos: 2.0s 51f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [277:0]
Pos: 2.1s 52f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [272:0]
Pos: 2.1s 53f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [266:0]
Pos: 2.2s 54f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [262:0]
Pos: 2.2s 55f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [257:0]
Pos: 2.2s 56f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [252:0]
Pos: 2.3s 57f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [248:0]
Pos: 2.3s 58f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [244:0]
Pos: 2.4s 59f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [240:0]
Pos: 2.4s 60f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [236:0]
Pos: 2.4s 61f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [232:0]
Pos: 2.5s 62f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [229:0]
Pos: 2.5s 63f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [225:0]
Pos: 2.6s 64f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [222:0]
Pos: 2.6s 65f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [218:0]
Pos: 2.6s 66f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [215:0]
Pos: 2.7s 67f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [212:0]
Pos: 2.7s 68f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [209:0]
Pos: 2.8s 69f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [206:0]
Pos: 2.8s 70f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [203:0]
Pos: 2.8s 71f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [200:0]
Pos: 2.9s 72f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [197:0]
Pos: 2.9s 73f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [195:0]
Pos: 3.0s 74f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [192:0]
Pos: 3.0s 75f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [190:0]
Pos: 3.0s 76f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [187:0]
Pos: 3.1s 77f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [185:0]
Pos: 3.1s 78f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [183:0]
Pos: 3.2s 79f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [180:0]
Pos: 3.2s 80f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [178:0]
Pos: 3.2s 81f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [176:0]
Pos: 3.3s 82f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [174:0]
Pos: 3.3s 83f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [172:0]
Pos: 3.4s 84f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [170:0]
Pos: 3.4s 85f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [168:0]
Pos: 3.4s 86f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [166:0]
Pos: 3.5s 87f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [164:0]
Pos: 3.5s 88f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [162:0]
Pos: 3.6s 89f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [161:0]
Pos: 3.6s 90f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [159:0]
Pos: 3.6s 91f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [157:0]
Pos: 3.7s 92f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [156:0]
Pos: 3.7s 93f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [154:0]
Pos: 3.8s 94f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [152:0]
Pos: 3.8s 95f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [151:0]
Pos: 3.8s 96f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [149:0]
Pos: 3.9s 97f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [148:0]
Pos: 3.9s 98f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [146:0]
Pos: 4.0s 99f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [145:0]
Pos: 4.0s 100f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [144:0]
Pos: 4.0s 101f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [142:0]
Pos: 4.1s 102f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [141:0]
Pos: 4.1s 103f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [140:0]
Pos: 4.2s 104f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [138:0]
Pos: 4.2s 105f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [137:0]
Pos: 4.2s 106f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [136:0]
Pos: 4.3s 107f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [135:0]
Pos: 4.3s 108f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [133:0]
Pos: 4.4s 109f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [132:0]
Pos: 4.4s 110f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [131:0]
Pos: 4.4s 111f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [130:0]
Pos: 4.5s 112f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [129:0]
Pos: 4.5s 113f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [128:0]
Pos: 4.6s 114f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [127:0]
Pos: 4.6s 115f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [126:0]
Pos: 4.6s 116f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [124:0]
Pos: 4.7s 117f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [123:0]
Pos: 4.7s 118f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [122:0]
Pos: 4.8s 119f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [121:0]
Pos: 4.8s 120f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [120:0]
Pos: 4.8s 121f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [119:0]
Pos: 4.9s 122f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [119:0]
Pos: 4.9s 123f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [118:0]
Pos: 5.0s 124f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [117:0]
Pos: 5.0s 125f (100%) 0.00fps Trem: 0min 0mb A-V:0.000 [116:0]
success: format: 0 data: 0x0 - 0x9daf8
libavformat file format detected.
[lavf] stream 0: video (h264), -vid 0
VIDEO: [H264] 640x400 24bpp 25.000 fps 21.8 kbps ( 2.7 kbyte/s)
[V] filefmt:44 fourcc:0x34363248 size:640x400 fps:25.000 ftime:=0.0400
videocodec: framecopy (540x800 24bpp fourcc=34363248)
videocodec: framecopy (640x400 24bpp fourcc=34363248)
All video files must have identical fps, resolution, and codec for -ovc copy.
Exiting... -
FFMPEG : cannot play MPEG4 video encoded from images. Duration and bitrate undefined
17 juin 2013, par KaiKI've been trying to set a H264 video stream created from images, into an MPEG4 container. I've been able to get the video stream from images successfully. But when muxing it in the container, I must do something wrong because no player is able to reproduce it, despite ffplay - that plays the video until the end and after that, the image gets frozen until the eternity -.
The ffplay cannot identify Duration neither bitrate, so I supose it might be an issue related with dts and pts, but I've searched about how to solve it with no success.
Here's the ffplay output :
~$ ffplay testContainer.mp4
ffplay version git-2012-01-31-c673671 Copyright (c) 2003-2012 the FFmpeg developers
built on Feb 7 2012 20:32:12 with gcc 4.4.3
configuration: --enable-gpl --enable-version3 --enable-nonfree --enable-postproc --enable- libfaac --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libtheora --enable-libvorbis --enable-libx264 --enable-libxvid --enable-x11grab --enable-libvpx --enable-libmp3lame --enable-debug=3
libavutil 51. 36.100 / 51. 36.100
libavcodec 54. 0.102 / 54. 0.102
libavformat 54. 0.100 / 54. 0.100
libavdevice 53. 4.100 / 53. 4.100
libavfilter 2. 60.100 / 2. 60.100
libswscale 2. 1.100 / 2. 1.100
libswresample 0. 6.100 / 0. 6.100
libpostproc 52. 0.100 / 52. 0.100
[h264 @ 0xa4849c0] max_analyze_duration 5000000 reached at 5000000
[h264 @ 0xa4849c0] Estimating duration from bitrate, this may be inaccurate
Input #0, h264, from 'testContainer.mp4':
Duration: N/A, bitrate: N/A
Stream #0:0: Video: h264 (High), yuv420p, 512x512, 25 fps, 25 tbr, 1200k tbn, 50 tbc
2.74 A-V: 0.000 fd= 0 aq= 0KB vq= 160KB sq= 0B f=0/0 0/0Structure
My code is C++ styled, so I've a class that handles all the encoding, and then a main that initilize it, passes some images in a bucle, and finally notify the end of the process as following :
int main (int argc, const char * argv[])
{
MyVideoEncoder* videoEncoder = new MyVideoEncoder(512, 512, 512, 512, "output/testContainer.mp4", 25, 20);
if(!videoEncoder->initWithCodec(MyVideoEncoder::H264))
{
std::cout << "something really bad happened. Exit!!" << std::endl;
exit(-1);
}
/* encode 1 second of video */
for(int i=0;i<228;i++) {
std::stringstream filepath;
filepath << "input2/image" << i << ".jpg";
videoEncoder->encodeFrameFromJPG(const_cast(filepath.str().c_str()));
}
videoEncoder->endEncoding();
}Hints
I've seen a lot of examples about decoding of a video and encoding into another, but no working example of muxing a video from the scratch, so I'm not sure how to proceed with the pts and dts packet values. That's the reason why I suspect the issue must be in the following method :
bool MyVideoEncoder::encodeImageAsFrame(){
bool res = false;
pTempFrame->pts = frameCount * frameRate * 90; //90Hz by the standard for PTS-values
frameCount++;
/* encode the image */
out_size = avcodec_encode_video(pVideoStream->codec, outbuf, outbuf_size, pTempFrame);
if (out_size > 0) {
AVPacket pkt;
av_init_packet(&pkt);
pkt.pts = pkt.dts = 0;
if (pVideoStream->codec->coded_frame->pts != AV_NOPTS_VALUE) {
pkt.pts = av_rescale_q(pVideoStream->codec->coded_frame->pts,
pVideoStream->codec->time_base, pVideoStream->time_base);
pkt.dts = pTempFrame->pts;
}
if (pVideoStream->codec->coded_frame->key_frame) {
pkt.flags |= AV_PKT_FLAG_KEY;
}
pkt.stream_index = pVideoStream->index;
pkt.data = outbuf;
pkt.size = out_size;
res = (av_interleaved_write_frame(pFormatContext, &pkt) == 0);
}
return res;
}Any help or insight would be appreciated. Thanks in advance !!
P.S. The rest of the code, where config is done, is the following :
// MyVideoEncoder.cpp
#include "MyVideoEncoder.h"
#include "Image.hpp"
#include <cstring>
#include <sstream>
#include
#define MAX_AUDIO_PACKET_SIZE (128 * 1024)
MyVideoEncoder::MyVideoEncoder(int inwidth, int inheight,
int outwidth, int outheight, char* fileOutput, int framerate,
int compFactor) {
inWidth = inwidth;
inHeight = inheight;
outWidth = outwidth;
outHeight = outheight;
pathToMovie = fileOutput;
frameRate = framerate;
compressionFactor = compFactor;
frameCount = 0;
}
MyVideoEncoder::~MyVideoEncoder() {
}
bool MyVideoEncoder::initWithCodec(
MyVideoEncoder::encoderType type) {
if (!initializeEncoder(type))
return false;
if (!configureFrames())
return false;
return true;
}
bool MyVideoEncoder::encodeFrameFromJPG(char* filepath) {
setJPEGImage(filepath);
return encodeImageAsFrame();
}
bool MyVideoEncoder::encodeDelayedFrames(){
bool res = false;
while(out_size > 0)
{
pTempFrame->pts = frameCount * frameRate * 90; //90Hz by the standard for PTS-values
frameCount++;
out_size = avcodec_encode_video(pVideoStream->codec, outbuf, outbuf_size, NULL);
if (out_size > 0)
{
AVPacket pkt;
av_init_packet(&pkt);
pkt.pts = pkt.dts = 0;
if (pVideoStream->codec->coded_frame->pts != AV_NOPTS_VALUE) {
pkt.pts = av_rescale_q(pVideoStream->codec->coded_frame->pts,
pVideoStream->codec->time_base, pVideoStream->time_base);
pkt.dts = pTempFrame->pts;
}
if (pVideoStream->codec->coded_frame->key_frame) {
pkt.flags |= AV_PKT_FLAG_KEY;
}
pkt.stream_index = pVideoStream->index;
pkt.data = outbuf;
pkt.size = out_size;
res = (av_interleaved_write_frame(pFormatContext, &pkt) == 0);
}
}
return res;
}
void MyVideoEncoder::endEncoding() {
encodeDelayedFrames();
closeEncoder();
}
bool MyVideoEncoder::setJPEGImage(char* imgFilename) {
Image* rgbImage = new Image();
rgbImage->read_jpeg_image(imgFilename);
bool ret = setImageFromRGBArray(rgbImage->get_data());
delete rgbImage;
return ret;
}
bool MyVideoEncoder::setImageFromRGBArray(unsigned char* data) {
memcpy(pFrameRGB->data[0], data, 3 * inWidth * inHeight);
int ret = sws_scale(img_convert_ctx, pFrameRGB->data, pFrameRGB->linesize,
0, inHeight, pTempFrame->data, pTempFrame->linesize);
pFrameRGB->pts++;
if (ret)
return true;
else
return false;
}
bool MyVideoEncoder::initializeEncoder(encoderType type) {
av_register_all();
pTempFrame = avcodec_alloc_frame();
pTempFrame->pts = 0;
pOutFormat = NULL;
pFormatContext = NULL;
pVideoStream = NULL;
pAudioStream = NULL;
bool res = false;
// Create format
switch (type) {
case MyVideoEncoder::H264:
pOutFormat = av_guess_format("h264", NULL, NULL);
break;
case MyVideoEncoder::MPEG1:
pOutFormat = av_guess_format("mpeg", NULL, NULL);
break;
default:
pOutFormat = av_guess_format(NULL, pathToMovie.c_str(), NULL);
break;
}
if (!pOutFormat) {
pOutFormat = av_guess_format(NULL, pathToMovie.c_str(), NULL);
if (!pOutFormat) {
std::cout << "output format not found" << std::endl;
return false;
}
}
// allocate context
pFormatContext = avformat_alloc_context();
if(!pFormatContext)
{
std::cout << "cannot alloc format context" << std::endl;
return false;
}
pFormatContext->oformat = pOutFormat;
memcpy(pFormatContext->filename, pathToMovie.c_str(), min( (const int) pathToMovie.length(), (const int)sizeof(pFormatContext->filename)));
//Add video and audio streams
pVideoStream = AddVideoStream(pFormatContext,
pOutFormat->video_codec);
// Set the output parameters
av_dump_format(pFormatContext, 0, pathToMovie.c_str(), 1);
// Open Video stream
if (pVideoStream) {
res = openVideo(pFormatContext, pVideoStream);
}
if (res && !(pOutFormat->flags & AVFMT_NOFILE)) {
if (avio_open(&pFormatContext->pb, pathToMovie.c_str(), AVIO_FLAG_WRITE) < 0) {
res = false;
std::cout << "Cannot open output file" << std::endl;
}
}
if (res) {
avformat_write_header(pFormatContext,NULL);
}
else{
freeMemory();
std::cout << "Cannot init encoder" << std::endl;
}
return res;
}
AVStream *MyVideoEncoder::AddVideoStream(AVFormatContext *pContext, CodecID codec_id)
{
AVCodecContext *pCodecCxt = NULL;
AVStream *st = NULL;
st = avformat_new_stream(pContext, NULL);
if (!st)
{
std::cout << "Cannot add new video stream" << std::endl;
return NULL;
}
st->id = 0;
pCodecCxt = st->codec;
pCodecCxt->codec_id = (CodecID)codec_id;
pCodecCxt->codec_type = AVMEDIA_TYPE_VIDEO;
pCodecCxt->frame_number = 0;
// Put sample parameters.
pCodecCxt->bit_rate = outWidth * outHeight * 3 * frameRate/ compressionFactor;
pCodecCxt->width = outWidth;
pCodecCxt->height = outHeight;
/* frames per second */
pCodecCxt->time_base= (AVRational){1,frameRate};
/* pixel format must be YUV */
pCodecCxt->pix_fmt = PIX_FMT_YUV420P;
if (pCodecCxt->codec_id == CODEC_ID_H264)
{
av_opt_set(pCodecCxt->priv_data, "preset", "slow", 0);
av_opt_set(pCodecCxt->priv_data, "vprofile", "baseline", 0);
pCodecCxt->max_b_frames = 16;
}
if (pCodecCxt->codec_id == CODEC_ID_MPEG1VIDEO)
{
pCodecCxt->mb_decision = 1;
}
if(pContext->oformat->flags & AVFMT_GLOBALHEADER)
{
pCodecCxt->flags |= CODEC_FLAG_GLOBAL_HEADER;
}
pCodecCxt->coder_type = 1; // coder = 1
pCodecCxt->flags|=CODEC_FLAG_LOOP_FILTER; // flags=+loop
pCodecCxt->me_range = 16; // me_range=16
pCodecCxt->gop_size = 50; // g=250
pCodecCxt->keyint_min = 25; // keyint_min=25
return st;
}
bool MyVideoEncoder::openVideo(AVFormatContext *oc, AVStream *pStream)
{
AVCodec *pCodec;
AVCodecContext *pContext;
pContext = pStream->codec;
// Find the video encoder.
pCodec = avcodec_find_encoder(pContext->codec_id);
if (!pCodec)
{
std::cout << "Cannot found video codec" << std::endl;
return false;
}
// Open the codec.
if (avcodec_open2(pContext, pCodec, NULL) < 0)
{
std::cout << "Cannot open video codec" << std::endl;
return false;
}
return true;
}
bool MyVideoEncoder::configureFrames() {
/* alloc image and output buffer */
outbuf_size = outWidth*outHeight*3;
outbuf = (uint8_t*) malloc(outbuf_size);
av_image_alloc(pTempFrame->data, pTempFrame->linesize, pVideoStream->codec->width,
pVideoStream->codec->height, pVideoStream->codec->pix_fmt, 1);
//Alloc RGB temp frame
pFrameRGB = avcodec_alloc_frame();
if (pFrameRGB == NULL)
return false;
avpicture_alloc((AVPicture *) pFrameRGB, PIX_FMT_RGB24, inWidth, inHeight);
pFrameRGB->pts = 0;
//Set SWS context to convert from RGB images to YUV images
if (img_convert_ctx == NULL) {
img_convert_ctx = sws_getContext(inWidth, inHeight, PIX_FMT_RGB24,
outWidth, outHeight, pVideoStream->codec->pix_fmt, /*SWS_BICUBIC*/
SWS_FAST_BILINEAR, NULL, NULL, NULL);
if (img_convert_ctx == NULL) {
fprintf(stderr, "Cannot initialize the conversion context!\n");
return false;
}
}
return true;
}
void MyVideoEncoder::closeEncoder() {
av_write_frame(pFormatContext, NULL);
av_write_trailer(pFormatContext);
freeMemory();
}
void MyVideoEncoder::freeMemory()
{
bool res = true;
if (pFormatContext)
{
// close video stream
if (pVideoStream)
{
closeVideo(pFormatContext, pVideoStream);
}
// Free the streams.
for(size_t i = 0; i < pFormatContext->nb_streams; i++)
{
av_freep(&pFormatContext->streams[i]->codec);
av_freep(&pFormatContext->streams[i]);
}
if (!(pFormatContext->flags & AVFMT_NOFILE) && pFormatContext->pb)
{
avio_close(pFormatContext->pb);
}
// Free the stream.
av_free(pFormatContext);
pFormatContext = NULL;
}
}
void MyVideoEncoder::closeVideo(AVFormatContext *pContext, AVStream *pStream)
{
avcodec_close(pStream->codec);
if (pTempFrame)
{
if (pTempFrame->data)
{
av_free(pTempFrame->data[0]);
pTempFrame->data[0] = NULL;
}
av_free(pTempFrame);
pTempFrame = NULL;
}
if (pFrameRGB)
{
if (pFrameRGB->data)
{
av_free(pFrameRGB->data[0]);
pFrameRGB->data[0] = NULL;
}
av_free(pFrameRGB);
pFrameRGB = NULL;
}
}
</sstream></cstring> -
FFMPEG : cannot play MPEG4 video encoded from images. Duration and bitrate undefined
17 juin 2013, par KaiKI've been trying to set a H264 video stream created from images, into an MPEG4 container. I've been able to get the video stream from images successfully. But when muxing it in the container, I must do something wrong because no player is able to reproduce it, despite ffplay - that plays the video until the end and after that, the image gets frozen until the eternity -.
The ffplay cannot identify Duration neither bitrate, so I supose it might be an issue related with dts and pts, but I've searched about how to solve it with no success.
Here's the ffplay output :
~$ ffplay testContainer.mp4
ffplay version git-2012-01-31-c673671 Copyright (c) 2003-2012 the FFmpeg developers
built on Feb 7 2012 20:32:12 with gcc 4.4.3
configuration: --enable-gpl --enable-version3 --enable-nonfree --enable-postproc --enable- libfaac --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libtheora --enable-libvorbis --enable-libx264 --enable-libxvid --enable-x11grab --enable-libvpx --enable-libmp3lame --enable-debug=3
libavutil 51. 36.100 / 51. 36.100
libavcodec 54. 0.102 / 54. 0.102
libavformat 54. 0.100 / 54. 0.100
libavdevice 53. 4.100 / 53. 4.100
libavfilter 2. 60.100 / 2. 60.100
libswscale 2. 1.100 / 2. 1.100
libswresample 0. 6.100 / 0. 6.100
libpostproc 52. 0.100 / 52. 0.100
[h264 @ 0xa4849c0] max_analyze_duration 5000000 reached at 5000000
[h264 @ 0xa4849c0] Estimating duration from bitrate, this may be inaccurate
Input #0, h264, from 'testContainer.mp4':
Duration: N/A, bitrate: N/A
Stream #0:0: Video: h264 (High), yuv420p, 512x512, 25 fps, 25 tbr, 1200k tbn, 50 tbc
2.74 A-V: 0.000 fd= 0 aq= 0KB vq= 160KB sq= 0B f=0/0 0/0Structure
My code is C++ styled, so I've a class that handles all the encoding, and then a main that initilize it, passes some images in a bucle, and finally notify the end of the process as following :
int main (int argc, const char * argv[])
{
MyVideoEncoder* videoEncoder = new MyVideoEncoder(512, 512, 512, 512, "output/testContainer.mp4", 25, 20);
if(!videoEncoder->initWithCodec(MyVideoEncoder::H264))
{
std::cout << "something really bad happened. Exit!!" << std::endl;
exit(-1);
}
/* encode 1 second of video */
for(int i=0;i<228;i++) {
std::stringstream filepath;
filepath << "input2/image" << i << ".jpg";
videoEncoder->encodeFrameFromJPG(const_cast(filepath.str().c_str()));
}
videoEncoder->endEncoding();
}Hints
I've seen a lot of examples about decoding of a video and encoding into another, but no working example of muxing a video from the scratch, so I'm not sure how to proceed with the pts and dts packet values. That's the reason why I suspect the issue must be in the following method :
bool MyVideoEncoder::encodeImageAsFrame(){
bool res = false;
pTempFrame->pts = frameCount * frameRate * 90; //90Hz by the standard for PTS-values
frameCount++;
/* encode the image */
out_size = avcodec_encode_video(pVideoStream->codec, outbuf, outbuf_size, pTempFrame);
if (out_size > 0) {
AVPacket pkt;
av_init_packet(&pkt);
pkt.pts = pkt.dts = 0;
if (pVideoStream->codec->coded_frame->pts != AV_NOPTS_VALUE) {
pkt.pts = av_rescale_q(pVideoStream->codec->coded_frame->pts,
pVideoStream->codec->time_base, pVideoStream->time_base);
pkt.dts = pTempFrame->pts;
}
if (pVideoStream->codec->coded_frame->key_frame) {
pkt.flags |= AV_PKT_FLAG_KEY;
}
pkt.stream_index = pVideoStream->index;
pkt.data = outbuf;
pkt.size = out_size;
res = (av_interleaved_write_frame(pFormatContext, &pkt) == 0);
}
return res;
}Any help or insight would be appreciated. Thanks in advance !!
P.S. The rest of the code, where config is done, is the following :
// MyVideoEncoder.cpp
#include "MyVideoEncoder.h"
#include "Image.hpp"
#include <cstring>
#include <sstream>
#include
#define MAX_AUDIO_PACKET_SIZE (128 * 1024)
MyVideoEncoder::MyVideoEncoder(int inwidth, int inheight,
int outwidth, int outheight, char* fileOutput, int framerate,
int compFactor) {
inWidth = inwidth;
inHeight = inheight;
outWidth = outwidth;
outHeight = outheight;
pathToMovie = fileOutput;
frameRate = framerate;
compressionFactor = compFactor;
frameCount = 0;
}
MyVideoEncoder::~MyVideoEncoder() {
}
bool MyVideoEncoder::initWithCodec(
MyVideoEncoder::encoderType type) {
if (!initializeEncoder(type))
return false;
if (!configureFrames())
return false;
return true;
}
bool MyVideoEncoder::encodeFrameFromJPG(char* filepath) {
setJPEGImage(filepath);
return encodeImageAsFrame();
}
bool MyVideoEncoder::encodeDelayedFrames(){
bool res = false;
while(out_size > 0)
{
pTempFrame->pts = frameCount * frameRate * 90; //90Hz by the standard for PTS-values
frameCount++;
out_size = avcodec_encode_video(pVideoStream->codec, outbuf, outbuf_size, NULL);
if (out_size > 0)
{
AVPacket pkt;
av_init_packet(&pkt);
pkt.pts = pkt.dts = 0;
if (pVideoStream->codec->coded_frame->pts != AV_NOPTS_VALUE) {
pkt.pts = av_rescale_q(pVideoStream->codec->coded_frame->pts,
pVideoStream->codec->time_base, pVideoStream->time_base);
pkt.dts = pTempFrame->pts;
}
if (pVideoStream->codec->coded_frame->key_frame) {
pkt.flags |= AV_PKT_FLAG_KEY;
}
pkt.stream_index = pVideoStream->index;
pkt.data = outbuf;
pkt.size = out_size;
res = (av_interleaved_write_frame(pFormatContext, &pkt) == 0);
}
}
return res;
}
void MyVideoEncoder::endEncoding() {
encodeDelayedFrames();
closeEncoder();
}
bool MyVideoEncoder::setJPEGImage(char* imgFilename) {
Image* rgbImage = new Image();
rgbImage->read_jpeg_image(imgFilename);
bool ret = setImageFromRGBArray(rgbImage->get_data());
delete rgbImage;
return ret;
}
bool MyVideoEncoder::setImageFromRGBArray(unsigned char* data) {
memcpy(pFrameRGB->data[0], data, 3 * inWidth * inHeight);
int ret = sws_scale(img_convert_ctx, pFrameRGB->data, pFrameRGB->linesize,
0, inHeight, pTempFrame->data, pTempFrame->linesize);
pFrameRGB->pts++;
if (ret)
return true;
else
return false;
}
bool MyVideoEncoder::initializeEncoder(encoderType type) {
av_register_all();
pTempFrame = avcodec_alloc_frame();
pTempFrame->pts = 0;
pOutFormat = NULL;
pFormatContext = NULL;
pVideoStream = NULL;
pAudioStream = NULL;
bool res = false;
// Create format
switch (type) {
case MyVideoEncoder::H264:
pOutFormat = av_guess_format("h264", NULL, NULL);
break;
case MyVideoEncoder::MPEG1:
pOutFormat = av_guess_format("mpeg", NULL, NULL);
break;
default:
pOutFormat = av_guess_format(NULL, pathToMovie.c_str(), NULL);
break;
}
if (!pOutFormat) {
pOutFormat = av_guess_format(NULL, pathToMovie.c_str(), NULL);
if (!pOutFormat) {
std::cout << "output format not found" << std::endl;
return false;
}
}
// allocate context
pFormatContext = avformat_alloc_context();
if(!pFormatContext)
{
std::cout << "cannot alloc format context" << std::endl;
return false;
}
pFormatContext->oformat = pOutFormat;
memcpy(pFormatContext->filename, pathToMovie.c_str(), min( (const int) pathToMovie.length(), (const int)sizeof(pFormatContext->filename)));
//Add video and audio streams
pVideoStream = AddVideoStream(pFormatContext,
pOutFormat->video_codec);
// Set the output parameters
av_dump_format(pFormatContext, 0, pathToMovie.c_str(), 1);
// Open Video stream
if (pVideoStream) {
res = openVideo(pFormatContext, pVideoStream);
}
if (res && !(pOutFormat->flags & AVFMT_NOFILE)) {
if (avio_open(&pFormatContext->pb, pathToMovie.c_str(), AVIO_FLAG_WRITE) < 0) {
res = false;
std::cout << "Cannot open output file" << std::endl;
}
}
if (res) {
avformat_write_header(pFormatContext,NULL);
}
else{
freeMemory();
std::cout << "Cannot init encoder" << std::endl;
}
return res;
}
AVStream *MyVideoEncoder::AddVideoStream(AVFormatContext *pContext, CodecID codec_id)
{
AVCodecContext *pCodecCxt = NULL;
AVStream *st = NULL;
st = avformat_new_stream(pContext, NULL);
if (!st)
{
std::cout << "Cannot add new video stream" << std::endl;
return NULL;
}
st->id = 0;
pCodecCxt = st->codec;
pCodecCxt->codec_id = (CodecID)codec_id;
pCodecCxt->codec_type = AVMEDIA_TYPE_VIDEO;
pCodecCxt->frame_number = 0;
// Put sample parameters.
pCodecCxt->bit_rate = outWidth * outHeight * 3 * frameRate/ compressionFactor;
pCodecCxt->width = outWidth;
pCodecCxt->height = outHeight;
/* frames per second */
pCodecCxt->time_base= (AVRational){1,frameRate};
/* pixel format must be YUV */
pCodecCxt->pix_fmt = PIX_FMT_YUV420P;
if (pCodecCxt->codec_id == CODEC_ID_H264)
{
av_opt_set(pCodecCxt->priv_data, "preset", "slow", 0);
av_opt_set(pCodecCxt->priv_data, "vprofile", "baseline", 0);
pCodecCxt->max_b_frames = 16;
}
if (pCodecCxt->codec_id == CODEC_ID_MPEG1VIDEO)
{
pCodecCxt->mb_decision = 1;
}
if(pContext->oformat->flags & AVFMT_GLOBALHEADER)
{
pCodecCxt->flags |= CODEC_FLAG_GLOBAL_HEADER;
}
pCodecCxt->coder_type = 1; // coder = 1
pCodecCxt->flags|=CODEC_FLAG_LOOP_FILTER; // flags=+loop
pCodecCxt->me_range = 16; // me_range=16
pCodecCxt->gop_size = 50; // g=250
pCodecCxt->keyint_min = 25; // keyint_min=25
return st;
}
bool MyVideoEncoder::openVideo(AVFormatContext *oc, AVStream *pStream)
{
AVCodec *pCodec;
AVCodecContext *pContext;
pContext = pStream->codec;
// Find the video encoder.
pCodec = avcodec_find_encoder(pContext->codec_id);
if (!pCodec)
{
std::cout << "Cannot found video codec" << std::endl;
return false;
}
// Open the codec.
if (avcodec_open2(pContext, pCodec, NULL) < 0)
{
std::cout << "Cannot open video codec" << std::endl;
return false;
}
return true;
}
bool MyVideoEncoder::configureFrames() {
/* alloc image and output buffer */
outbuf_size = outWidth*outHeight*3;
outbuf = (uint8_t*) malloc(outbuf_size);
av_image_alloc(pTempFrame->data, pTempFrame->linesize, pVideoStream->codec->width,
pVideoStream->codec->height, pVideoStream->codec->pix_fmt, 1);
//Alloc RGB temp frame
pFrameRGB = avcodec_alloc_frame();
if (pFrameRGB == NULL)
return false;
avpicture_alloc((AVPicture *) pFrameRGB, PIX_FMT_RGB24, inWidth, inHeight);
pFrameRGB->pts = 0;
//Set SWS context to convert from RGB images to YUV images
if (img_convert_ctx == NULL) {
img_convert_ctx = sws_getContext(inWidth, inHeight, PIX_FMT_RGB24,
outWidth, outHeight, pVideoStream->codec->pix_fmt, /*SWS_BICUBIC*/
SWS_FAST_BILINEAR, NULL, NULL, NULL);
if (img_convert_ctx == NULL) {
fprintf(stderr, "Cannot initialize the conversion context!\n");
return false;
}
}
return true;
}
void MyVideoEncoder::closeEncoder() {
av_write_frame(pFormatContext, NULL);
av_write_trailer(pFormatContext);
freeMemory();
}
void MyVideoEncoder::freeMemory()
{
bool res = true;
if (pFormatContext)
{
// close video stream
if (pVideoStream)
{
closeVideo(pFormatContext, pVideoStream);
}
// Free the streams.
for(size_t i = 0; i < pFormatContext->nb_streams; i++)
{
av_freep(&pFormatContext->streams[i]->codec);
av_freep(&pFormatContext->streams[i]);
}
if (!(pFormatContext->flags & AVFMT_NOFILE) && pFormatContext->pb)
{
avio_close(pFormatContext->pb);
}
// Free the stream.
av_free(pFormatContext);
pFormatContext = NULL;
}
}
void MyVideoEncoder::closeVideo(AVFormatContext *pContext, AVStream *pStream)
{
avcodec_close(pStream->codec);
if (pTempFrame)
{
if (pTempFrame->data)
{
av_free(pTempFrame->data[0]);
pTempFrame->data[0] = NULL;
}
av_free(pTempFrame);
pTempFrame = NULL;
}
if (pFrameRGB)
{
if (pFrameRGB->data)
{
av_free(pFrameRGB->data[0]);
pFrameRGB->data[0] = NULL;
}
av_free(pFrameRGB);
pFrameRGB = NULL;
}
}
</sstream></cstring>