
Recherche avancée
Médias (1)
-
Rennes Emotion Map 2010-11
19 octobre 2011, par
Mis à jour : Juillet 2013
Langue : français
Type : Texte
Autres articles (60)
-
Ajouter notes et légendes aux images
7 février 2011, parPour pouvoir ajouter notes et légendes aux images, la première étape est d’installer le plugin "Légendes".
Une fois le plugin activé, vous pouvez le configurer dans l’espace de configuration afin de modifier les droits de création / modification et de suppression des notes. Par défaut seuls les administrateurs du site peuvent ajouter des notes aux images.
Modification lors de l’ajout d’un média
Lors de l’ajout d’un média de type "image" un nouveau bouton apparait au dessus de la prévisualisation (...) -
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 (...) -
HTML5 audio and video support
13 avril 2011, parMediaSPIP uses HTML5 video and audio tags to play multimedia files, taking advantage of the latest W3C innovations supported by modern browsers.
The MediaSPIP player used has been created specifically for MediaSPIP and can be easily adapted to fit in with a specific theme.
For older browsers the Flowplayer flash fallback is used.
MediaSPIP allows for media playback on major mobile platforms with the above (...)
Sur d’autres sites (7747)
-
apng : Add a basic APNG encoder
31 mars 2015, par Donny Yang -
FFmpeg wrong output duration after av_seek_frame
18 septembre 2022, par GogogoI try to transcode a video and also cut it, but in the output file, I get the wrong duration for the file(video duration is correct). It happens when I seek the video, as an example, if I try cut from 60000 to 63000 ms I will get :
Format : WebM
Format version : Version 2
File size : 17.6 KiB
Duration : 1 min 4 s
Overall bit rate : 2 232 b/s
Writing application : Lavf59.31.100
Writing library : Lavf59.31.100


Video
ID : 1
Format : VP9
Codec ID : V_VP9
Duration : 2 s 961 ms
Width : 100 pixels
Height : 100 pixels
Display aspect ratio : 1.000
Frame rate mode : Constant
Frame rate : 24.000 FPS
Default : No
Forced : No


Here is my code, what I am doing wrong ?


namespace {
 
 constexpr auto maxDurationMs = 3000;
 constexpr auto maxFileSizeByte = 100000;
 
 struct StreamingParams {
 std::string output_extension;
 std::string muxer_opt_key;
 std::string muxer_opt_value;
 std::string video_codec;
 std::string codec_priv_key;
 std::string codec_priv_value;
 };
 
 struct StreamingContext {
 AVFormatContext* avfc = nullptr;
 AVCodec* video_avc = nullptr;
 AVStream* video_avs = nullptr;
 AVCodecContext* video_avcc = nullptr;
 int video_index = 0;
 std::string filename;
 ~StreamingContext() {}
 };
 
 struct StreamingContextDeleter {
 void operator()(StreamingContext* context) {
 if (context) {
 auto* avfc = &context->avfc;
 auto* avcc = &context->video_avcc;
 if (avfc)
 avformat_close_input(avfc);
 if (avcc)
 avcodec_free_context(avcc);
 if (context->avfc)
 avformat_free_context(context->avfc);
 }
 }
 };
 
 struct AVFrameDeleter {
 void operator()(AVFrame* frame) {
 if (frame)
 av_frame_free(&frame);
 }
 };
 
 struct AVPacketDeleter {
 void operator()(AVPacket* packet) {
 if (packet)
 av_packet_free(&packet);
 }
 };
 
 struct SwsContextDeleter {
 void operator()(SwsContext* context) {
 if (context)
 sws_freeContext(context);
 }
 };
 
 struct AVDictionaryDeleter {
 void operator()(AVDictionary* dictionary) {
 if (dictionary)
 av_dict_free(&dictionary);
 }
 };
 
 int fill_stream_info(AVStream* avs, AVCodec** avc, AVCodecContext** avcc) {
 *avc = const_cast(avcodec_find_decoder(avs->codecpar->codec_id));
 if (!*avc) return -1;

 *avcc = avcodec_alloc_context3(*avc);
 if (!*avcc) return -1;
 if (avcodec_parameters_to_context(*avcc, avs->codecpar) < 0) return -1;
 if (avcodec_open2(*avcc, *avc, nullptr) < 0) return -1;

 return 0;
 }
 
 int open_media(const char* in_filename, AVFormatContext** avfc) {
 *avfc = avformat_alloc_context();
 if (!*avfc) return -1;
 if (avformat_open_input(avfc, in_filename, nullptr, nullptr) != 0) return -1;
 if (avformat_find_stream_info(*avfc, nullptr) < 0) return -1;
 
 return 0;
 }
 
 int prepare_decoder(std::shared_ptr<streamingcontext> sc) {
 for (int i = 0; i < 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;
 }
 }
 
 return 0;
 }
 
 int prepare_video_encoder(std::shared_ptr<streamingcontext> sc,
 AVCodecContext* decoder_ctx,
 AVRational input_framerate,
 const StreamingParams& sp) {
 sc->video_avs = avformat_new_stream(sc->avfc, nullptr);
 
 sc->video_avc = const_cast(
 avcodec_find_encoder_by_name(sp.video_codec.c_str()));
 if (!sc->video_avc) return -1;
 
 sc->video_avcc = avcodec_alloc_context3(sc->video_avc);
 if (!sc->video_avcc) return -1;
 
 av_opt_set(sc->video_avcc->priv_data, "preset", "fast", 0);

 sc->video_avcc->height = 100;
 sc->video_avcc->width = 100;
 sc->video_avcc->sample_aspect_ratio = decoder_ctx->sample_aspect_ratio;
 if (sc->video_avc->pix_fmts)
 sc->video_avcc->pix_fmt = sc->video_avc->pix_fmts[0];
 else
 sc->video_avcc->pix_fmt = decoder_ctx->pix_fmt;
 
 constexpr int64_t maxBitrate = maxFileSizeByte / (maxDurationMs / 1000.0) - 1;
 
 sc->video_avcc->bit_rate = maxBitrate;
 sc->video_avcc->rc_buffer_size = decoder_ctx->rc_buffer_size;
 sc->video_avcc->rc_max_rate = maxBitrate;
 sc->video_avcc->rc_min_rate = maxBitrate;
 sc->video_avcc->time_base = av_inv_q(input_framerate);
 sc->video_avs->time_base = sc->video_avcc->time_base;
 
 if (avcodec_open2(sc->video_avcc, sc->video_avc, nullptr) < 0) return -1;
 avcodec_parameters_from_context(sc->video_avs->codecpar, sc->video_avcc);
 
 return 0;
 }
 
 int encode_video(std::shared_ptr<streamingcontext> decoder,
 std::shared_ptr<streamingcontext> encoder,
 AVFrame* input_frame) {
 if (input_frame)
 input_frame->pict_type = AV_PICTURE_TYPE_NONE;
 
 AVPacket* output_packet = av_packet_alloc();
 if (!output_packet) return -1;
 
 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;
 } else if (response < 0) return -1;
 
 output_packet->stream_index = decoder->video_index;
 output_packet->duration = encoder->video_avs->time_base.den /
 encoder->video_avs->time_base.num /
 decoder->video_avs->avg_frame_rate.num *
 decoder->video_avs->avg_frame_rate.den;
 
 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);
 if (response != 0) return -1;
 }
 av_packet_unref(output_packet);
 av_packet_free(&output_packet);
 return 0;
 }
 
 int transcode_video(std::shared_ptr<streamingcontext> decoder,
 std::shared_ptr<streamingcontext> encoder,
 AVPacket* input_packet,
 AVFrame* input_frame) {
 int response = avcodec_send_packet(decoder->video_avcc, input_packet);
 if (response < 0) return response;

 
 while (response >= 0) {
 response = avcodec_receive_frame(decoder->video_avcc, input_frame);
 if (response == AVERROR(EAGAIN) || response == AVERROR_EOF) {
 break;
 } else if (response < 0) return response;
 
 if (response >= 0) {
 if (encode_video(decoder, encoder, input_frame)) return -1;
 }
 av_frame_unref(input_frame);
 }
 
 return 0;
 }
 
 } // namespace
 
 
 int VideoToGifConverter::convert(VideoProp input, QString output) {
 StreamingParams sp;
 sp.output_extension = ".webm";
 sp.video_codec = "libvpx-vp9";
 
 auto inputStd = input.path.toStdString();
 auto outputStd =
 (output + '/' + QUuid::createUuid().toString(QUuid::StringFormat::Id128))
 .toStdString() +
 sp.output_extension;
 
 auto decoder = std::shared_ptr<streamingcontext>(new StreamingContext,
 StreamingContextDeleter{});
 auto encoder = std::shared_ptr<streamingcontext>(new StreamingContext,
 StreamingContextDeleter{});
 
 encoder->filename = std::move(outputStd);
 decoder->filename = std::move(inputStd);
 
 if (open_media(decoder->filename.c_str(), &decoder->avfc))
 return -1;
 if (prepare_decoder(decoder))
 return -1;
 
 avformat_alloc_output_context2(&encoder->avfc, nullptr, nullptr,
 encoder->filename.c_str());
 if (!encoder->avfc) return -1;
 
 AVRational input_framerate =
 av_guess_frame_rate(decoder->avfc, decoder->video_avs, nullptr);
 prepare_video_encoder(encoder, decoder->video_avcc, input_framerate, sp);
 
 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.c_str(),
 AVIO_FLAG_WRITE) < 0) return -1;
 }
 
 AVDictionary* muxer_opts = nullptr;
 
 if (!sp.muxer_opt_key.empty() && !sp.muxer_opt_value.empty()) {
 av_dict_set(&muxer_opts, sp.muxer_opt_key.c_str(),
 sp.muxer_opt_value.c_str(), 0);
 }
 
 if (avformat_write_header(encoder->avfc, &muxer_opts) < 0) return -1;
 
 auto inputFrame = std::unique_ptr(av_frame_alloc());
 if (!inputFrame) return -1;
 
 auto inputPacket =
 std::unique_ptr(av_packet_alloc());
 if (!inputPacket) return -1;
 
 auto** streams = decoder->avfc->streams;
 
 const auto fps = static_cast<double>(
 streams[inputPacket->stream_index]->avg_frame_rate.num) /
 streams[inputPacket->stream_index]->avg_frame_rate.den;
 const size_t beginFrame = input.beginPosMs * fps / 1000;
 const size_t endFrame = input.endPosMs * fps / 1000;
 const auto totalFrames = endFrame - beginFrame;
 
 size_t count = 0;
 
 int64_t startTime =
 av_rescale_q(input.beginPosMs * AV_TIME_BASE / 1000, {1, AV_TIME_BASE},
 decoder->video_avs->time_base);
 
 av_seek_frame(decoder->avfc, inputPacket->stream_index, startTime, 0);
 avcodec_flush_buffers(decoder->video_avcc);
 
 while (count < totalFrames &&
 av_read_frame(decoder->avfc, inputPacket.get()) >= 0) {
 if (streams[inputPacket->stream_index]->codecpar->codec_type ==
 AVMEDIA_TYPE_VIDEO) {
 if (transcode_video(decoder, encoder, inputPacket.get(), inputFrame.get())) {
 return -1;
 }
 ++count;
 }
 av_packet_unref(inputPacket.get());
 }
 
 if (encode_video(decoder, encoder, nullptr, nullptr)) return -1;
 
 av_write_trailer(encoder->avfc);
 
 return 0;
 }
</double></streamingcontext></streamingcontext></streamingcontext></streamingcontext></streamingcontext></streamingcontext></streamingcontext></streamingcontext>


-
ffmpeg difference when using -lavfi or -filter_complex
25 mai 2020, par Luiz CieslakI've started to use ffmpeg recently. I have been using only the -filter_complex flag to apply filters. I stumbled upon this SO question :






A ffmpeg maintainer answers it using the -lavfi flag :



ffmpeg -i input.mp4 -lavfi "[0:v]scale=iw:2*trunc(iw*16/18),boxblur=luma_radius=min(h\,w)/20:luma_power=1:chroma_radius=min(cw\,ch)/20:chroma_power=1[bg];[bg][0:v]overlay=(W-w)/2:(H-h)/2,setsar=1" output.mp4



I tried to change -lavfi flag to -filter_complex :



ffmpeg -i input.mp4 -filter_complex "[0:v]scale=iw:2*trunc(iw*16/18),boxblur=luma_radius=min(h\,w)/20:luma_power=1:chroma_radius=min(cw\,ch)/20:chroma_power=1[bg];[bg][0:v]overlay=(W-w)/2:(H-h)/2,setsar=1" output.mp4



The result is the same and didn't notice a perf change.



Is there a difference when using either flags ?