Recherche avancée

Médias (0)

Mot : - Tags -/alertes

Aucun média correspondant à vos critères n’est disponible sur le site.

Autres articles (66)

Sur d’autres sites (13939)

  • Encoding images to h264 and rtp output : SDP file without sprop-parameter-sets does not play

    14 septembre 2021, par oarfish

    tl ;dr : I try to encode acquired camera frames to h264, send via RTP
and play this back on another device. SDP file generated by ffmpeg for
a sample video has info which my own SDP file misses. My SDP file
plays in ffplay, but not VLC, while both play ffmpeg's SDP file. I am
suspecting missing sprop-parameter-sets in my SDP file.

    


    Ultimately I want to play this back in VLC.

    



    


    I am writing code that encodes images to h264 and outputs to an RTP
server (or client ? anyway the part that is listening). I generate an
SDP file for this.

    


      

    • ffplay plays the stream without problem
    • 


    • mplayer shows a green box embedded in a larger black box, but I read
somewhere it only supports mpegts over RTP, so not sure
    • 


    • VLC does not play the SDP file.
    • 


    


    Now when instead I use some random video and have ffmpeg output an SDP
file like so

    


    ffmpeg     -re     -i some.mp4     -an     -c:v copy -f rtp -sdp_file
video.sdp     "rtp://127.0.0.1:5004"


    


    I can see that the generated SDP file – which plays in both ffplay and
VLC – includes the base64 encoded sprop-parameter-sets field, and
removing this causes the stream to not play.

    


    > cat video.sdp
v=0
o=- 0 0 IN IP4 127.0.0.1
s=No Name
c=IN IP4 127.0.0.1
t=0 0
a=tool:libavformat 58.76.100
m=video 5004 RTP/AVP 96
b=AS:1034
a=rtpmap:96 H264/90000
a=fmtp:96 packetization-mode=1;
sprop-parameter-sets=Z2QANKzZQDAA7fiMBagICAoAAAMAAgAAAwDwHjBjLA==,aOvjyyLA;
profile-level-id=640034


    


    My own SDP file on the other hand, does not contain this information,
and VLC hangs for 10s and then stops trying with "no data received".

    


    > cat test.sdp
v=0
o=- 0 0 IN IP4 127.0.0.1
s=No Name
c=IN IP4 127.0.0.1
t=0 0
a=tool:libavformat 58.76.100
m=video 44499 RTP/AVP 96
b=AS:2000
a=rtpmap:96 H264/90000
a=fmtp:96 packetization-mode=1


    


    So my theory is that my custom code must somehow add this SPS
information to the SDP file. But despite hours of searching, I could
not find a structured way to set the extradata field on the AVStream's
AVCodecParams. The code I'm using is roughly this (I'm sure there's
unrelated errors in there) :

    


    // variables&#xA;std::vector imgbuf;&#xA;AVFormatContext *ofmt_ctx = nullptr;&#xA;AVCodec *out_codec = nullptr;&#xA;AVStream *out_stream = nullptr;&#xA;AVCodecContext *out_codec_ctx = nullptr;&#xA;SwsContext *swsctx = nullptr;&#xA;cv::Mat canvas_;&#xA;unsigned int height_;&#xA;unsigned int width_;&#xA;unsigned int fps_;&#xA;AVFrame *frame_ = nullptr;&#xA;&#xA;AVOutputFormat *format = av_guess_format("rtp", nullptr, nullptr);&#xA;const auto url = std::string("rtp://127.0.0.1:5001");&#xA;avformat_alloc_output_context2(ofmt_ctx, format, format->name, url.c_str());&#xA;&#xA;out_codec = avcodec_find_encoder(AV_CODEC_ID_H264);&#xA;stream = avformat_new_stream(ofmt_ctx, out_codec);&#xA;out_codec_ctx = avcodec_alloc_context3(out_codec);&#xA;&#xA;// then, for each incoming image:&#xA;while (receive_image) {&#xA;  static bool first_time = true;&#xA;  if (first_time) {&#xA;    // discover necessary params such as image dimensions from the first&#xA;    // received image&#xA;    first_time = false;&#xA;    height_ = image.rows;&#xA;    width_ = image.cols;&#xA;&#xA;    codec_ctx->codec_tag = 0;&#xA;    codec_ctx->bit_rate = 2e6;&#xA;    // does nothing, unfortunately&#xA;    codec_ctx->thread_count = 1;&#xA;    codec_ctx->codec_id = AV_CODEC_ID_H264;&#xA;    codec_ctx->codec_type = AVMEDIA_TYPE_VIDEO;&#xA;    codec_ctx->width = width_;&#xA;    codec_ctx->height = height_;&#xA;    codec_ctx->gop_size = 6;&#xA;    codec_ctx->pix_fmt = AV_PIX_FMT_YUV420P;&#xA;    codec_ctx->framerate = fps_;&#xA;    codec_ctx->time_base = av_inv_q(fps_);&#xA;&#xA;    avcodec_parameters_from_context(stream, out_codec_ctx);&#xA;&#xA;    // this stuff is empty: is that the problem?&#xA;    stream->codecpar->extradata = codec_ctx->extradata;&#xA;    stream->codecpar->extradata_size = codec_ctx->extradata_size;&#xA;&#xA;    AVDictionary *codec_options = nullptr;&#xA;    av_dict_set(&amp;codec_options, "profile", "high", 0);&#xA;    av_dict_set(&amp;codec_options, "preset", "ultrafast", 0);&#xA;    av_dict_set(&amp;codec_options, "tune", "zerolatency", 0);&#xA;&#xA;    // open video encoder&#xA;    avcodec_open2(codec_ctx, codec, &amp;codec_options);&#xA;&#xA;    stream->time_base.num = 1;&#xA;    stream->time_base.den = fps_;&#xA;    avio_open(&amp;(ofmt_ctx->pb), ofmt_ctx->filename, AVIO_FLAG_WRITE);&#xA;&#xA;    /* Write a file for VLC */&#xA;    char buf[200000];&#xA;    AVFormatContext *ac[] = {ofmt_ctx};&#xA;    av_sdp_create(ac, 1, buf, 20000);&#xA;    printf("sdp:\n%s\n", buf);&#xA;    FILE *fsdp = fopen("test.sdp", "w");&#xA;    fprintf(fsdp, "%s", buf);&#xA;    fclose(fsdp);&#xA;&#xA;    swsctx = sws_getContext(width_, height_, AV_PIX_FMT_BGR24, width_, height_,&#xA;                            out_codec_ctx->pix_fmt, SWS_BICUBIC, nullptr,&#xA;                            nullptr, nullptr);&#xA;  }&#xA;&#xA;  if (!frame_) {&#xA;    frame_ = av_frame_alloc();&#xA;&#xA;    std::uint8_t *framebuf = new uint8_t[av_image_get_buffer_size(&#xA;        codec_ctx->pix_fmt, width_, height_, 1)];&#xA;    av_image_fill_arrays(frame_->data, frame_->linesize, framebuf,&#xA;                         codec_ctx->pix_fmt, width, height, 1);&#xA;    frame_->width = width_;&#xA;    frame_->height = height_;&#xA;    frame_->format = static_cast<int>(codec_ctx->pix_fmt);&#xA;    success = avformat_write_header(ofmt_ctx, nullptr);&#xA;  }&#xA;  if (imgbuf.empty()) {&#xA;    imgbuf.resize(height_ * width_ * 3 &#x2B; 16);&#xA;    canvas_ = cv::Mat(height_, width_, CV_8UC3, imgbuf.data(), width_ * 3);&#xA;  } else {&#xA;    image.copyTo(canvas_);&#xA;  }&#xA;&#xA;  const int stride[] = {static_cast<int>(image.step[0])};&#xA;&#xA;  sws_scale(swsctx, &amp;canvas_.data, stride, 0, canvas_.rows, frame_->data,&#xA;            frame_->linesize);&#xA;  frame_->pts &#x2B;= av_rescale_q(1, out_codec_ctx->time_base, stream->time_base);&#xA;&#xA;  AVPacket pkt = {0};&#xA;  avcodec_send_frame(out_codec_ctx, frame_);&#xA;  avcodec_receive_packet(out_codec_ctx, &amp;pkt);&#xA;  av_interleaved_write_frame(ofmt_ctx, &amp;pkt);&#xA;}&#xA;</int></int>

    &#xA;

    Can anyone offer some advice here ?

    &#xA;

    &#xA;

    Update

    &#xA;

    When setting

    &#xA;

    this->out_codec_ctx->flags |=AV_CODEC_FLAG_GLOBAL_HEADER;&#xA;

    &#xA;

    extradata is actually present in the codec context, but I had to move avcodec_parameters_from_context() after avcodec_open2(), as the extradata is empty before opening the codec. I now get sprop-parameter-sets in the SDP file, but VLC still does not play it.

    &#xA;

  • unable to download youtube video portion via extracted video URL from youtube-dl and ffmpeg

    29 juillet 2020, par karma

    I've read the following link, and did :

    &#xA;

    youtube-dl --rm-cache-dir&#xA;

    &#xA;

    But it still give me 403 forbidden.

    &#xA;

    This is my process :

    &#xA;

    youtube-dl -g https://www.youtube.com/watch?v=kGDgGsrA78s&#xA;

    &#xA;

    It gave me a result like this :

    &#xA;

    https://r2---sn-uigxxi0ujipnvo-q2ne.googlevideo.com/videoplayback?expire=1596034295&amp;ei=lzghX6SHKMOD8QPlx5SQBw&amp;ip=223.255.228.87&amp;id=o-AK6cYo88zJXe5Xb4y1QsXspuRnVCy-zPFpMaHcAaTQ-_&amp;itag=137&amp;aitags=133%2C134%2C135%2C136%2C137%2C160%2C242%2C243%2C244%2C247%2C248%2C278&amp;source=youtube&amp;requiressl=yes&amp;mh=DA&amp;mm=31%2C29&amp;mn=sn-uigxxi0ujipnvo-q2ne%2Csn-npoe7nlz&amp;ms=au%2Crdu&amp;mv=m&amp;mvi=2&amp;pl=24&amp;initcwndbps=173750&amp;vprv=1&amp;mime=video%2Fmp4&amp;gir=yes&amp;clen=456970484&amp;dur=1389.955&amp;lmt=1521825834085900&amp;mt=1596012582&amp;fvip=5&amp;keepalive=yes&amp;fexp=23883098&amp;c=WEB&amp;sparams=expire%2Cei%2Cip%2Cid%2Caitags%2Csource%2Crequiressl%2Cvprv%2Cmime%2Cgir%2Cclen%2Cdur%2Clmt&amp;sig=AOq0QJ8wRgIhAMvZrHYvC1YrkvtARzhjyD8dnMnlefobGrOFM1rX6QZPAiEAqqeIsKdZ19y-SlHf-l8YwTx2yYbo1p5sFlVoC87oXEQ%3D&amp;lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&amp;lsig=AG3C_xAwRAIgAIwAVMPrcMhAL476uN_ZzWj8vKPGGW58KCpHBYBsKeICICRgVWgthNvgbGl8VgQwscjJ0n8ib4XBNjRxRgSg2T5r&amp;ratebypass=yes&#xA;https://r2---sn-uigxxi0ujipnvo-q2ne.googlevideo.com/videoplayback?expire=1596034295&amp;ei=lzghX6SHKMOD8QPlx5SQBw&amp;ip=223.255.228.87&amp;id=o-AK6cYo88zJXe5Xb4y1QsXspuRnVCy-zPFpMaHcAaTQ-_&amp;itag=140&amp;source=youtube&amp;requiressl=yes&amp;mh=DA&amp;mm=31%2C29&amp;mn=sn-uigxxi0ujipnvo-q2ne%2Csn-npoe7nlz&amp;ms=au%2Crdu&amp;mv=m&amp;mvi=2&amp;pl=24&amp;initcwndbps=173750&amp;vprv=1&amp;mime=audio%2Fmp4&amp;gir=yes&amp;clen=22077901&amp;dur=1390.039&amp;lmt=1521818817521456&amp;mt=1596012582&amp;fvip=5&amp;keepalive=yes&amp;fexp=23883098&amp;c=WEB&amp;sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cvprv%2Cmime%2Cgir%2Cclen%2Cdur%2Clmt&amp;sig=AOq0QJ8wRQIhANHMaZK4jYg7p4t2dID3d21VRv18I1nhBtXqYRSZo0C7AiAEjO8LwjhXeNQiKqdiZFQ_DsHuXT4rgvPnNQhaDGj9hg%3D%3D&amp;lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&amp;lsig=AG3C_xAwRAIgAIwAVMPrcMhAL476uN_ZzWj8vKPGGW58KCpHBYBsKeICICRgVWgthNvgbGl8VgQwscjJ0n8ib4XBNjRxRgSg2T5r&amp;ratebypass=yes&#xA;

    &#xA;

    The result gave me two URL, so I only copy the first line and since what I want is just to copy a few minutes video portion - so in ffmpeg :

    &#xA;

    ffmpeg -ss 00:00:15.00 -i https://r2---sn-uigxxi0ujipnvo-q2ne.googlevideo.com/videoplayback?expire=1596034295&amp;ei=lzghX6SHKMOD8QPlx5SQBw&amp;ip=223.255.228.87&amp;id=o-AK6cYo88zJXe5Xb4y1QsXspuRnVCy-zPFpMaHcAaTQ-_&amp;itag=140&amp;source=youtube&amp;requiressl=yes&amp;mh=DA&amp;mm=31%2C29&amp;mn=sn-uigxxi0ujipnvo-q2ne%2Csn-npoe7nlz&amp;ms=au%2Crdu&amp;mv=m&amp;mvi=2&amp;pl=24&amp;initcwndbps=173750&amp;vprv=1&amp;mime=audio%2Fmp4&amp;gir=yes&amp;clen=22077901&amp;dur=1390.039&amp;lmt=1521818817521456&amp;mt=1596012582&amp;fvip=5&amp;keepalive=yes&amp;fexp=23883098&amp;c=WEB&amp;sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cvprv%2Cmime%2Cgir%2Cclen%2Cdur%2Clmt&amp;sig=AOq0QJ8wRQIhANHMaZK4jYg7p4t2dID3d21VRv18I1nhBtXqYRSZo0C7AiAEjO8LwjhXeNQiKqdiZFQ_DsHuXT4rgvPnNQhaDGj9hg%3D%3D&amp;lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&amp;lsig=AG3C_xAwRAIgAIwAVMPrcMhAL476uN_ZzWj8vKPGGW58KCpHBYBsKeICICRgVWgthNvgbGl8VgQwscjJ0n8ib4XBNjRxRgSg2T5r&amp;ratebypass=yes -t 00:00:10.00 -c copy out.mp4&#xA;

    &#xA;

    But then the result in command prompt is like this :

    &#xA;

    ffmpeg version N-93300-g96451477b9 Copyright (c) 2000-2019 the FFmpeg developers&#xA;  built with gcc 8.2.1 (GCC) 20190212&#xA;  configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libmfx --enable-amf --enable-ffnvcodec --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt&#xA;  libavutil      56. 26.100 / 56. 26.100&#xA;  libavcodec     58. 47.103 / 58. 47.103&#xA;  libavformat    58. 26.101 / 58. 26.101&#xA;  libavdevice    58.  6.101 / 58.  6.101&#xA;  libavfilter     7. 48.100 /  7. 48.100&#xA;  libswscale      5.  4.100 /  5.  4.100&#xA;  libswresample   3.  4.100 /  3.  4.100&#xA;  libpostproc    55.  4.100 / 55.  4.100&#xA;[https @ 0000020137c895c0] HTTP error 403 Forbidden&#xA;https://r2---sn-uigxxi0ujipnvo-q2ne.googlevideo.com/videoplayback?expire=1596034295: Server returned 403 Forbidden (access denied)&#xA;&#x27;ei&#x27; is not recognized as an internal or external command,&#xA;operable program or batch file.&#xA;&#x27;ip&#x27; is not recognized as an internal or external command,&#xA;operable program or batch file.&#xA;&#x27;id&#x27; is not recognized as an internal or external command,&#xA;operable program or batch file.&#xA;.... and so on....&#xA;

    &#xA;

    BTW, I've also tried to copy the second URL, still 403 error.
    &#xA;I also tried to copy both URL, still 403 error.

    &#xA;

    On the other hand, when I tried to paste the URL into Internet Download Manager,
    &#xA;IDM directly recognized the URL and I can download the file via IDM.

    &#xA;

    Is there a way to resolve this ?

    &#xA;

    Any kind of respond would be greatly appreciated.
    &#xA;Thank you in advanced.

    &#xA;

    EDIT :&#xA;I'm very sorry for my ignorant.
    &#xA;It turn out I need to put apostrophe at the beginning and at the end of the URL :).

    &#xA;

    Dear moderator, please close this thread.
    &#xA;Thank you for you all.

    &#xA;

  • FFmpeg : What re-encoding settings can be used to achieve results similar to Google Drive's video processing ?

    4 août 2023, par Mycroft_47

    Context :

    &#xA;

    I have a large collection of videos recorded by my phone's camera, which is taking up a significant amount of space. Recently, I noticed that when I uploaded a video to Google Drive and then downloaded it again using IDM (by clicking on the pop-up that IDM displays when it detects something that can be downloaded here's what i mean), the downloaded video retained the same visual quality but occupied much less space. Upon further research, I discovered that Google re-encodes uploaded videos using H.264 video encoding, and I believe I can achieve similar compression using FFmpeg.

    &#xA;

    Problem :

    &#xA;

    Despite experimenting with various FFmpeg commands, I haven't been able to replicate Google Drive's compression. Every attempt using -codec:v libx264 option alone resulted in videos larger than the original files.

    &#xA;

    While adjusting the -crf parameter to a higher value and opting for a faster -preset option did yield smaller file sizes, it unfortunately came at the cost of a noticeable degradation in visual quality and the appearance of some visible artifacts in the video.

    &#xA;

    Google Drive's processing, on the other hand, strikes a commendable balance, achieving a satisfactory file size without compromising visual clarity, (I should note that upon zooming in on this video, I observed some minor blurring, but it was acceptable to me).

    &#xA;

    Note :

    &#xA;

    I'm aware that using the H.265 video encoder instead of H.264 may give better results. However, to ensure fairness and avoid any potential bias, I think the optimal approach is first to find the best command using the H.264 video encoder. Once identified, I can then replace -codec:v libx264 with -codec:v libx265. This approach will ensure that the chosen command is really the best that FFMPEG can achieve, and that it is not solely influenced by the superior performance of H.265 when used from the outset.

    &#xA;

    Here's the FFMPEG command I am currently using :

    &#xA;

    ffmpeg -hide_banner -loglevel verbose ^&#xA;    -i input.mp4 ^&#xA;    -codec:v libx264 ^&#xA;    -crf 36 -preset ultrafast ^&#xA;    -codec:a libopus -b:a 112k ^&#xA;    -movflags use_metadata_tags&#x2B;faststart -map_metadata 0 ^&#xA;    output.mp4&#xA;

    &#xA;

    &#xA;&#xA;&#xA;&#xA;

    &#xA;

    &#xA;

    &#xA;

    &#xA;

    &#xA;

    &#xA;

    &#xA;

    &#xA;&#xA;

    &#xA;

    &#xA;

    &#xA;

    &#xA;

    &#xA;

    &#xA;

    &#xA;

    &#xA;

    &#xA;

    &#xA;

    &#xA;

    &#xA;

    &#xA;

    &#xA;

    &#xA;

    &#xA;

    &#xA;

    &#xA;

    &#xA;

    &#xA;

    &#xA;

    &#xA;

    &#xA;

    &#xA;

    &#xA;

    &#xA;

    &#xA;

    &#xA;

    Video file Size (bytes) Bit rate (bps) Encoder FFPROB - JSON
    Original (named 'raw 1.mp4') 31,666,777 10,314,710  !!! link
    Without crf 36,251,852 11,805,216 Lavf60.3.100 link
    With crf 10,179,113 3,314,772 Lavf60.3.100 link
    Gdrive 6,726,189 2,190,342 Google link

    &#xA;

    &#xA;

    Those files can be found here.

    &#xA;

    Update :

    &#xA;

    I continued my experiments with the video "raw_1.mp4" and found some interesting results that resemble those shown in this blog post, (I recommend consulting this answer).

    &#xA;

    In the following figure, I observed that using the -preset set to veryfast provided the most advantageous results, striking the optimal balance between compression ratio and compression time, (Note that a negative percentage in the compression variable indicates an increase in file size after processing) :&#xA;enter image description here

    &#xA;

    In this figure, I used the H.264 encoder and compared the compression ratio of different outputted files resulting from seven different values of the -crf parameter (CRF values used : 25, 27, 29, 31, 33, 35, 37),&#xA;enter image description here

    &#xA;

    For this figure, I've switched the encoder to H.265 while maintaining the same CRF values used in the previous figure :&#xA;enter image description here

    &#xA;

    Based on these results, the -preset veryfast and a -crf value of 31 are my current preferred settings for FFmpeg, until they are proven to be suboptimal choices.&#xA;As a result, the FFmpeg command I'll use is as follows :

    &#xA;

    ffmpeg -hide_banner -loglevel verbose ^&#xA;    -i input.mp4 ^&#xA;    -codec:v libx264 ^&#xA;    -crf 31 -preset veryfast ^&#xA;    -codec:a libopus -b:a 112k ^&#xA;    -movflags use_metadata_tags&#x2B;faststart -map_metadata 0 ^&#xA;    output.mp4&#xA;

    &#xA;

    Note that these choices are based solely on the compression results obtained so far, and they do not take into account the visual quality of the outputted files.

    &#xA;