
Recherche avancée
Autres articles (34)
-
Configuration spécifique d’Apache
4 février 2011, parModules spécifiques
Pour la configuration d’Apache, il est conseillé d’activer certains modules non spécifiques à MediaSPIP, mais permettant d’améliorer les performances : mod_deflate et mod_headers pour compresser automatiquement via Apache les pages. Cf ce tutoriel ; mode_expires pour gérer correctement l’expiration des hits. Cf ce tutoriel ;
Il est également conseillé d’ajouter la prise en charge par apache du mime-type pour les fichiers WebM comme indiqué dans ce tutoriel.
Création d’un (...) -
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 ;
-
Gestion générale des documents
13 mai 2011, parMédiaSPIP ne modifie jamais le document original mis en ligne.
Pour chaque document mis en ligne il effectue deux opérations successives : la création d’une version supplémentaire qui peut être facilement consultée en ligne tout en laissant l’original téléchargeable dans le cas où le document original ne peut être lu dans un navigateur Internet ; la récupération des métadonnées du document original pour illustrer textuellement le fichier ;
Les tableaux ci-dessous expliquent ce que peut faire MédiaSPIP (...)
Sur d’autres sites (6210)
-
Revision 37442 : On se base sur la valeur de l’id_orig pour vérifier si l’on doit mettre ...
20 avril 2010, par kent1@… — LogOn se base sur la valeur de l’id_orig pour vérifier si l’on doit mettre dans la file d’encodage et non pas sur le nom de fichier
Incrément mineur de version -
ERROR "Application provided invalid, non monotonically increasing dts to muxer in stream 1 : 6874 >= 6874" while writing encoded output to an mp4 file
11 mai 2023, par lokit khemkaI have a running RTSP stream, streaming video on a loop using the following FFMPEG command :


ffmpeg -re -stream_loop -1 -i ./ffmpeg_c_test/small_bunny_1080p_60fps.mp4 -ac 2 -f rtsp -rtsp_transport tcp rtsp://localhost:8554/mystream



The video file is obtained from the github link : https://github.com/leandromoreira/ffmpeg-libav-tutorial


I keep getting error response, when I calling the function
av_interleaved_write_frame
called from the functionremux
in the attached program. The output format ismp4
, output video codec isav1
and output audio codec is same as input audio codec. The error is from audio stream.

I tried to create a "minimal reproducible code", however, I think it is still not completely minimal, but it reproduces the exact error.


#include <libavcodec></libavcodec>avcodec.h>
#include <libavformat></libavformat>avformat.h>
#include <libavutil></libavutil>timestamp.h>
#include <libavutil></libavutil>opt.h>
#include <libswscale></libswscale>swscale.h>
#include 
#include 
#include 

#include 
#include 

typedef struct StreamingContext{
 AVFormatContext* avfc;
 const AVCodec *video_avc;
 const AVCodec *audio_avc;
 AVStream *video_avs;
 AVStream *audio_avs;
 AVCodecContext *video_avcc;
 AVCodecContext *audio_avcc;
 int video_index;
 int audio_index;
 char* filename;
 struct SwsContext *sws_ctx;
}StreamingContext;


typedef struct StreamingParams{
 char copy_video;
 char copy_audio;
 char *output_extension;
 char *muxer_opt_key;
 char *muxer_opt_value;
 char *video_codec;
 char *audio_codec;
 char *codec_priv_key;
 char *codec_priv_value;
}StreamingParams;

void logging(const char *fmt, ...)
{
 va_list args;
 fprintf(stderr, "LOG: ");
 va_start(args, fmt);
 vfprintf(stderr, fmt, args);
 va_end(args);
 fprintf(stderr, "\n");
}

int fill_stream_info(AVStream *avs, const AVCodec **avc, AVCodecContext **avcc)
{
 *avc = avcodec_find_decoder(avs->codecpar->codec_id);
 *avcc = avcodec_alloc_context3(*avc);
 if (avcodec_parameters_to_context(*avcc, avs->codecpar) < 0)
 {
 logging("Failed to fill Codec Context.");
 return -1;
 }
 avcodec_open2(*avcc, *avc, NULL);
 return 0;
}

int open_media(const char *in_filename, AVFormatContext **avfc)
{
 *avfc = avformat_alloc_context();
 if (avformat_open_input(avfc, in_filename, NULL, NULL) != 0)
 {
 logging("Failed to open input file %s", in_filename);
 return -1;
 }

 if (avformat_find_stream_info(*avfc, NULL) < 0)
 {
 logging("Failed to get Stream Info.");
 return -1;
 }
}

int prepare_decoder(StreamingContext *sc)
{
 for (int i = 0; i < (int)sc->avfc->nb_streams; i++)
 {
 if (sc->avfc->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
 {
 sc->video_avs = sc->avfc->streams[i];
 sc->video_index = i;

 if (fill_stream_info(sc->video_avs, &sc->video_avc, &sc->video_avcc))
 {
 return -1;
 }
 }
 else if (sc->avfc->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
 {
 sc->audio_avs = sc->avfc->streams[i];
 sc->audio_index = i;

 if (fill_stream_info(sc->audio_avs, &sc->audio_avc, &sc->audio_avcc))
 {
 return -1;
 }
 }
 else
 {
 logging("Skipping Streams other than Audio and Video.");
 }
 }
 return 0;
}

int prepare_video_encoder(StreamingContext *encoder_sc, AVCodecContext *decoder_ctx, AVRational input_framerate,
 StreamingParams sp, int scaled_frame_width, int scaled_frame_height)
{
 encoder_sc->video_avs = avformat_new_stream(encoder_sc->avfc, NULL);
 encoder_sc->video_avc = avcodec_find_encoder_by_name(sp.video_codec);
 if (!encoder_sc->video_avc)
 {
 logging("Cannot find the Codec.");
 return -1;
 }

 encoder_sc->video_avcc = avcodec_alloc_context3(encoder_sc->video_avc);
 if (!encoder_sc->video_avcc)
 {
 logging("Could not allocate memory for Codec Context.");
 return -1;
 }

 av_opt_set(encoder_sc->video_avcc->priv_data, "preset", "fast", 0);
 if (sp.codec_priv_key && sp.codec_priv_value)
 av_opt_set(encoder_sc->video_avcc->priv_data, sp.codec_priv_key, sp.codec_priv_value, 0);

 encoder_sc->video_avcc->height = scaled_frame_height;
 encoder_sc->video_avcc->width = scaled_frame_width;
 encoder_sc->video_avcc->sample_aspect_ratio = decoder_ctx->sample_aspect_ratio;

 if (encoder_sc->video_avc->pix_fmts)
 encoder_sc->video_avcc->pix_fmt = encoder_sc->video_avc->pix_fmts[0];
 else
 encoder_sc->video_avcc->pix_fmt = decoder_ctx->pix_fmt;

 encoder_sc->video_avcc->bit_rate = 2 * 1000 * 1000;

 encoder_sc->video_avcc->time_base = av_inv_q(input_framerate);
 encoder_sc->video_avs->time_base = encoder_sc->video_avcc->time_base;

 

 if (avcodec_open2(encoder_sc->video_avcc, encoder_sc->video_avc, NULL) < 0)
 {
 logging("Could not open the Codec.");
 return -1;
 }
 avcodec_parameters_from_context(encoder_sc->video_avs->codecpar, encoder_sc->video_avcc);
 return 0;
}


int prepare_copy(AVFormatContext *avfc, AVStream **avs, AVCodecParameters *decoder_par)
{
 *avs = avformat_new_stream(avfc, NULL);
 avcodec_parameters_copy((*avs)->codecpar, decoder_par);
 return 0;
}

int encode_video(StreamingContext *decoder, StreamingContext *encoder, AVFrame *input_frame)
{
 if (input_frame)
 input_frame->pict_type = AV_PICTURE_TYPE_NONE;

 AVPacket *output_packet = av_packet_alloc();


 int response = avcodec_send_frame(encoder->video_avcc, input_frame);

 while (response >= 0)
 {
 response = avcodec_receive_packet(encoder->video_avcc, output_packet);
 if (response == AVERROR(EAGAIN) || response == AVERROR_EOF)
 {
 break;
 }

 output_packet->stream_index = decoder->video_index;
 output_packet->duration = encoder->video_avs->time_base.den / encoder->video_avs->time_base.num;

 av_packet_rescale_ts(output_packet, decoder->video_avs->time_base, encoder->video_avs->time_base);
 response = av_interleaved_write_frame(encoder->avfc, output_packet);
 }

 av_packet_unref(output_packet);
 av_packet_free(&output_packet);

 return 0;
}

int remux(AVPacket **pkt, AVFormatContext **avfc, AVRational decoder_tb, AVRational encoder_tb)
{
 (*pkt)->duration = av_rescale_q((*pkt)->duration, decoder_tb, encoder_tb);
 (*pkt)->pos = -1;
 av_packet_rescale_ts(*pkt, decoder_tb, encoder_tb);
 if (av_interleaved_write_frame(*avfc, *pkt) < 0)
 {
 logging("Error while copying Stream Packet.");
 return -1;
 }
 return 0;
}

int transcode_video(StreamingContext *decoder, StreamingContext *encoder, AVPacket *input_packet, AVFrame *input_frame)
{
 int response = avcodec_send_packet(decoder->video_avcc, input_packet);
 while (response >= 0)
 {
 response = avcodec_receive_frame(decoder->video_avcc, input_frame);
 
 if (response == AVERROR(EAGAIN) || response == AVERROR_EOF)
 {
 break;
 }
 if (response >= 0)
 {
 if (encode_video(decoder, encoder, input_frame))
 return -1;
 }

 av_frame_unref(input_frame);
 }
 return 0;
}

int main(int argc, char *argv[])
{
 const int scaled_frame_width = 854;
 const int scaled_frame_height = 480;
 StreamingParams sp = {0};
 sp.copy_audio = 1;
 sp.copy_video = 0;
 sp.video_codec = "libsvtav1";
 
 StreamingContext *decoder = (StreamingContext *)calloc(1, sizeof(StreamingContext));
 decoder->filename = "rtsp://localhost:8554/mystream";

 StreamingContext *encoder = (StreamingContext *)calloc(1, sizeof(StreamingContext));
 encoder->filename = "small_bunny_9.mp4";
 
 if (sp.output_extension)
 {
 strcat(encoder->filename, sp.output_extension);
 }

 open_media(decoder->filename, &decoder->avfc);
 prepare_decoder(decoder);


 avformat_alloc_output_context2(&encoder->avfc, NULL, "mp4", encoder->filename);
 AVRational input_framerate = av_guess_frame_rate(decoder->avfc, decoder->video_avs, NULL);
 prepare_video_encoder(encoder, decoder->video_avcc, input_framerate, sp, scaled_frame_width, scaled_frame_height);

 prepare_copy(encoder->avfc, &encoder->audio_avs, decoder->audio_avs->codecpar);
 

 if (encoder->avfc->oformat->flags & AVFMT_GLOBALHEADER)
 encoder->avfc->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;

 if (!(encoder->avfc->oformat->flags & AVFMT_NOFILE))
 {
 if (avio_open(&encoder->avfc->pb, encoder->filename, AVIO_FLAG_WRITE) < 0)
 {
 logging("could not open the output file");
 return -1;
 }
 }

 
 if (avformat_write_header(encoder->avfc, NULL) < 0)
 {
 logging("an error occurred when opening output file");
 return -1;
 }

 AVFrame *input_frame = av_frame_alloc();
 AVPacket *input_packet = av_packet_alloc();

 while (1)
 {
 int ret = av_read_frame(decoder->avfc, input_packet);
 if(ret<0)
 break;
 if (decoder->avfc->streams[input_packet->stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
 {
 if (transcode_video(decoder, encoder, input_packet, input_frame))
 return -1;
 av_packet_unref(input_packet);

 }
 else if (decoder->avfc->streams[input_packet->stream_index]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
 {
 
 if (remux(&input_packet, &encoder->avfc, decoder->audio_avs->time_base, encoder->audio_avs->time_base))
 return -1;
 }
 else
 {
 logging("Ignoring all nonvideo or audio packets.");
 }
 }

 if (encode_video(decoder, encoder, NULL))
 return -1;
 

 av_write_trailer(encoder->avfc);


 if (input_frame != NULL)
 {
 av_frame_free(&input_frame);
 input_frame = NULL;
 }

 if (input_packet != NULL)
 {
 av_packet_free(&input_packet);
 input_packet = NULL;
 }

 avformat_close_input(&decoder->avfc);

 avformat_free_context(decoder->avfc);
 decoder->avfc = NULL;
 avformat_free_context(encoder->avfc);
 encoder->avfc = NULL;

 avcodec_free_context(&decoder->video_avcc);
 decoder->video_avcc = NULL;
 avcodec_free_context(&decoder->audio_avcc);
 decoder->audio_avcc = NULL;

 free(decoder);
 decoder = NULL;
 free(encoder);
 encoder = NULL;

 return 0;
}




-
Clip long video segment quickly
30 janvier 2020, par PRManLet’s say I have a video called Concert.mp4. I want to extract a performance from it quickly with minimal reencoding. I want to do the equivalent of this, but faster :
ffmpeg -i "Concert.mp4" -ss 00:11:45 -to 00:18:15 -preset veryfast -y artist.mp4
This takes 17 seconds, which is way too long for our needs.
Now, it turns out that 11:45 and 18:15 don’t fall on iframes, so if you try this you will get a 3 second delay at the beginning before the video shows :
ffmpeg -i "Concert.mp4" -ss 00:11:45 -to 00:18:15 -c copy -y artist.mp4
Running this command, we can see where we need to cut :
ffprobe -read_intervals "11:00%19:00" -v error -skip_frame nokey -show_entries frame=pkt_pts_time -select_streams v -of csv=p=0 "Concert.mp4" > frames.txt
So what we need to do is encode the first 3.708 seconds, copy the middle, and then encode the last 5.912 seconds.
I can get the 3 segments to all look perfect (by themselves) like this :
ffmpeg -ss 698.698 -i "Concert.mp4" -ss 6.302 -t 3.708 -c:v libx264 -c:a copy -c:s copy -y clipbegin.mp4
ffmpeg -ss 708.708 -to 1089.088 -i "Concert.mp4" -c copy -y clipmiddle.mp4
ffmpeg -ss 1089.088 -i "Concert.mp4" -t 5.912 -c:v libx264 -c:a copy -c:s copy -y clipend.mp4
ffmpeg -f concat -i segments.txt -c copy -y artist.mp4segments.txt of course contains the following :
file 'clipbegin.mkv'
file 'clipmiddle.mkv'
file 'clipend.mkv'I saw this solution presented here, but no amount of tweaking gets it to work for me :
https://superuser.com/a/1039134/73272
As far as I can tell, this method doesn’t work at all. It crashes VLC pretty hard no matter what I try.
The combined video keeps glitching after the 3 seconds, probably because the PTS times are different or something (using some options, I have seen warning messages to this effect). Is there anything I can add to the commands above to get this to work ? The only requirement is that the middle command must not re-encode the video, but must do a fast copy.
Thanks in advance.