Newest 'ffmpeg' Questions - Stack Overflow
Les articles publiés sur le site
-
FFmpeg : Remux f4v cutted from stream to mp4
13 mai 2019, par MartinI have a mp4 file cutted from a H.264/AAC stream with Wowza Media Server. After the cutting, the file was forced to mp4 format with the following command:
ffmpeg -i wowza_output_file -vcodec copy -acodec copy -f mp4 -y wowza_output_file_copy
From there I renamed it to test_f4v.mp4 and took ffprobe, to take a look at the file:
ffprobe version 0.8, Copyright (c) 2007-2011 the FFmpeg developers built on Jul 20 2011 13:32:19 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 libavutil 51. 9. 1 / 51. 9. 1 libavcodec 53. 7. 0 / 53. 7. 0 libavformat 53. 4. 0 / 53. 4. 0 libavdevice 53. 1. 1 / 53. 1. 1 libavfilter 2. 23. 0 / 2. 23. 0 libswscale 2. 0. 0 / 2. 0. 0 libpostproc 51. 2. 0 / 51. 2. 0 Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'test_f4v.mp4': Metadata: major_brand : f4v minor_version : 0 compatible_brands: isommp42m4v creation_time : 2012-04-23 12:36:06 Duration: 01:00:01.84, start: 0.000000, bitrate: 2004 kb/s Stream #0.0(eng): Video: h264 (Baseline), yuv420p, 854x480 [PAR 1:1 DAR 427:240], 1903 kb/s, 25 fps, 25 tbr, 90k tbn, 50 tbc Metadata: creation_time : 2012-04-23 12:36:06 Stream #0.1(eng): Audio: aac, 48000 Hz, stereo, s16, 96 kb/s Metadata: creation_time : 2012-04-23 12:36:06
Now there is a problem. I need a file, which has the following meta data:
major_brand : mp42 compatible_brands: isom
Is there a way to remux the mp4 file to get the
major_brand
andcompatible_brands
to the described values with ffmpeg? -
look for an mp4 file inside a directory and send it to different directory after converting to mp3 in php ?
13 mai 2019, par flashI have a directory called incoming_folder in which there is an mp4 file.
What I want to achieve through php code is to scan a incoming_folder directory, look for an mp4 file and send it to outgoing_folder after converting it into mp3. Technically outgoing_folder should have mp3 version of mp4 from incoming_folder
Tried with the following code although its scanning the incoming_folder directory but no conversion is happening through ffmpeg.
<?php $dir = 'in_folder'; /* Place where mp4 file is present */ $files1 = scandir($dir); print_r($files1); /* It lists all the files in a directory including mp4 file*/ $destination = 'out_folder'; /* Place where mp3 file need to be send after conversion from mp4 */ foreach($files1 as $f) { $parts = pathinfo($f); switch($parts['extension']) { case 'mp4' : system('ffmpeg -i '.$f.' -map 0:2 -ac 1 '.$destination.DS. $parts['filename'].'.mp3', $result); if ($result) { // Do something with result if you want // log for example } break; case 'mp3' : // copy($f, $destination. DS . $parts['filename']. '.' . $parts['extension']); copy($f, $destination.DS.$parts['filename'].'.mp3'); break; } } ?>
-
Why does ffmpeg with libfdk_aac encoding cuts away 25ms in the beginning of an audio file ?
13 mai 2019, par vkuzmaI switched encoding from aac to libfdk_aac due to qaulity issues. I noticed with the new encoding a small part of the audio file will be cut in the beginning. I tested this with multiple files. This is the command i am using:
ffmpeg -y -noaccurate_seek -i file.mp3 -b:a 260k -c:a libfdk_aac -vn -movflags +faststart output.m4a
I tried different variations but alway ended up with cut file.
Here is the output of a wave editor
source file:
ouput:
-
FFMpeg : how to use between() to select last second ?
13 mai 2019, par rcpinheiroI'm trying to apply a caption using drawtext that should disappear one second before the video end:
ffmpeg -i input.mp4 -vf "drawtext=enable='between(t,0,5)':fontfile=font.ttf:text='Some caption':x=60:y=640:fontsize=40:fontcolor=#f0f0f0@0.9" -vcodec libx264 -crf 27 -preset ultrafast -strict -2 -acodec copy output.mp4
The problem is that I don't know the video length beforehand. I've tried using 'between(t,0,-1)' but it doesn't work, the caption never shows up. Anyone knows if is there a way to do this without having to open the video first to check length and only after that draw the caption? Thanks in advance!
-
Capture desktop with gdigrab and save the result to video file using ffmpeg and C++
13 mai 2019, par SkunzI'm building a C++ application that is able to capture the screen and save the output to a file (.mkv, .mp4, doesn't matter).
I tried to switch codecs and played with the AVCodecContext settings. When subsitute the gdi capture with reading from a static .mp4 file everything works fine.
Here is my gdigrab initalization.
_inputFormat = av_find_input_format("gdigrab"); if (!_inputFormat) { std::cout << "Unable to open input Format" << std::endl; exit(1); } if (avformat_open_input(&_screenFormatContext, "desktop", _inputFormat, &_recordOptions) < 0) { std::cout << "Unable to open input stream" << std::endl; exit(1); } if (avformat_find_stream_info(_screenFormatContext, &_recordOptions) < 0) { std::cout << "Couldn't find input stream" << std::endl; exit(1); } av_dump_format(_screenFormatContext, 0, "GDI Capture", 0); for (int i = 0; i < _screenFormatContext->nb_streams; i++) { if (_screenFormatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { _videoStreamIdx = i; break; } } if (_videoStreamIdx == -1) { std::cout << "Unable to find video Stream" << std::endl; exit(1); } _codecPar = _screenFormatContext->streams[_videoStreamIdx]->codecpar;
Here is my setup code for the encoder and decoder.
/* Decoder */ _dCodec = avcodec_find_decoder(_codecPar->codec_id); if (!_dCodec) { std::cout << "Unable to find decoder" << std::endl; exit(1); } _dCodecContext = avcodec_alloc_context3(_dCodec); if (avcodec_parameters_to_context(_dCodecContext, _codecPar) < 0) { std::cout << "Unable to copy context" << std::endl; exit(1); } if (avcodec_open2(_dCodecContext, _dCodec, NULL) < 0) { std::cout << "Unable to open dCodec" << std::endl; exit(1); } /* Encoder */ _eCodec = avcodec_find_encoder(AV_CODEC_ID_H265); if (!_eCodec) { std::cout << "Unable to find encoder" << std::endl; exit(1); } _eCodecContext = avcodec_alloc_context3(_eCodec); //width and height have to be divisible by 2 if (_codecPar->width % 2 != 0) _codecPar->width--; if (_codecPar->height % 2 != 0) _codecPar->height--; _eCodecContext->pix_fmt = AV_PIX_FMT_YUV422P; _eCodecContext->width = _codecPar->width; _eCodecContext->height = _codecPar->height; _eCodecContext->gop_size = 10; _eCodecContext->max_b_frames = 1; _eCodecContext->time_base.den = 30; _eCodecContext->time_base.num = 1; if (avcodec_open2(_eCodecContext, _eCodec, NULL) < 0) { std::cout << "Unable to open eCodec" << std::endl; exit(1); }
Here is my main loop. Grabbing the packets from gdi, decoding them and encoding them.
while (av_read_frame(_screenFormatContext, _pkt) == 0) { if (_pkt->stream_index == _videoStreamIdx) { if (_decodePacket() < 0) exit(1); _encodeFrame(); } av_packet_unref(_pkt); }
And here the encoding/decoding functions
int ScreenRecorder::_decodePacket(void) { //send packet to decoder int ret = avcodec_send_packet(_dCodecContext, _pkt); if (ret < 0) { std::cout << "error while sending packet to decoder" << std::endl; return ret; } ret = avcodec_receive_frame(_dCodecContext, _frame); if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) return 0; //Was there an error? else if (ret < 0) { std::cout << "Error with receiving frame" << std::endl; exit(1); } //No errors -> got frame std::cout << "Got frame " << _dCodecContext->frame_number << " with size " << _frame->pkt_size << std::endl; char frame_filename[1024]; snprintf(frame_filename, sizeof(frame_filename), "%s-%d.pgm", "frame", _dCodecContext->frame_number); //_saveGrayFrame(_frame->data[0], _frame->linesize[0], _frame->width, _frame->height, frame_filename); return 0; } void ScreenRecorder::_encodeFrame(void) { AVPacket* pkt = av_packet_alloc(); // send frame to encoder - 0 on success int ret = avcodec_send_frame(_eCodecContext, _frame); if (ret < 0) { std::cerr << "Unable to send frame! ERRORCODE: " << ret << std::endl; exit(1); } while (ret == 0) { ret = avcodec_receive_packet(_eCodecContext, pkt); //Do I need to send more packets? if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { std::cout << "Needing one more packet " << std::endl; av_packet_unref(pkt); return ; } //Was there an error? else if (ret < 0) { std::cout << "Error with receiving packet" << std::endl; exit(1); } //No errors -> got packet std::cout << "Got packet " << pkt->pts << " of size " << pkt->size << std::endl; if (av_write_frame(_outFormatContext, pkt) < 0) { std::cout << "Unable to write frame" << std::endl; exit(1); } av_packet_unref(pkt); } }
In case you still need the header file
#ifndef SCREENRECORDER_HPP # define SCREENRECORDER_HPP extern "C" { #include "libavcodec/avcodec.h" #include "libavdevice/avdevice.h" #include "libavformat/avformat.h" #include "libavformat/avio.h" } class ScreenRecorder { private: AVCodecContext *_dCodecContext; AVCodecContext *_eCodecContext; AVFormatContext *_fileFormatContext; AVFormatContext *_screenFormatContext; AVFormatContext *_outFormatContext; AVInputFormat *_inputFormat; AVCodecParameters *_codecPar; AVStream *_videoTrack; AVCodec *_dCodec; AVCodec *_eCodec; AVFrame *_frame; AVPacket *_pkt; AVDictionary *_options; AVDictionary *_recordOptions; int _videoStreamIdx; int _decodePacket(void); void _encodeFrame(void); void _openInputFile(void); void _initalizeCodec(void); void _initalizeOutputFile(void); void _closeCodec(void); void _initalizeGDI(void); void _saveGrayFrame(unsigned char* buf, int wrap, int xsize, int ysize, char* filename); public: ScreenRecorder(); ~ScreenRecorder(); void start(); }; #endif
When I run my code I am getting Exception thrown at 0x00007FF819864A80 (msvcrt.dll) in Streaming.exe: 0xC0000005: Access violation reading location 0x0000000000000EF0. It comes from avcodec_send_frame function. Seems like I'm trying to access memory that wasn't allocated. I am new to the ffmpeg lib and hope that someone can get me on the right track. Thank you very much. If you have any questions please ask them.