Recherche avancée

Médias (91)

Autres articles (104)

  • Soumettre améliorations et plugins supplémentaires

    10 avril 2011

    Si vous avez développé une nouvelle extension permettant d’ajouter une ou plusieurs fonctionnalités utiles à MediaSPIP, faites le nous savoir et son intégration dans la distribution officielle sera envisagée.
    Vous pouvez utiliser la liste de discussion de développement afin de le faire savoir ou demander de l’aide quant à la réalisation de ce plugin. MediaSPIP étant basé sur SPIP, il est également possible d’utiliser le liste de discussion SPIP-zone de SPIP pour (...)

  • Emballe médias : à quoi cela sert ?

    4 février 2011, par

    Ce plugin vise à gérer des sites de mise en ligne de documents de tous types.
    Il crée des "médias", à savoir : un "média" est un article au sens SPIP créé automatiquement lors du téléversement d’un document qu’il soit audio, vidéo, image ou textuel ; un seul document ne peut être lié à un article dit "média" ;

  • ANNEXE : Les plugins utilisés spécifiquement pour la ferme

    5 mars 2010, par

    Le site central/maître de la ferme a besoin d’utiliser plusieurs plugins supplémentaires vis à vis des canaux pour son bon fonctionnement. le plugin Gestion de la mutualisation ; le plugin inscription3 pour gérer les inscriptions et les demandes de création d’instance de mutualisation dès l’inscription des utilisateurs ; le plugin verifier qui fournit une API de vérification des champs (utilisé par inscription3) ; le plugin champs extras v2 nécessité par inscription3 (...)

Sur d’autres sites (10473)

  • FFMPEG Presentation Time Stamps (PTS) calculation in RTSP stream

    8 décembre 2020, par BadaBudaBudu

    Below please find en raw example of my code for your better understanding of what it does. Please note that this is an updated (removed deprecated methods, etc.) example code by myself from the official FFMPEG documentation complemented by my encoder.

    


    /// STD&#xA;#include <iostream>&#xA;#include <string>&#xA;&#xA;/// FFMPEG&#xA;extern "C"&#xA;{&#xA;    #include <libavformat></libavformat>avformat.h>&#xA;    #include <libswscale></libswscale>swscale.h>&#xA;    #include <libavutil></libavutil>imgutils.h>&#xA;}&#xA;&#xA;/// VideoLib&#xA;#include <tools></tools>multimediaprocessing.h>&#xA;#include &#xA;#include &#xA;#include <enums></enums>codec.h>&#xA;#include <enums></enums>pixelformat.h>&#xA;&#xA;/// OpenCV&#xA;#include <opencv2></opencv2>opencv.hpp>&#xA;&#xA;inline static const char *inputRtspAddress = "rtsp://192.168.0.186:8080/video/h264";&#xA;&#xA;int main()&#xA;{&#xA;    AVFormatContext* formatContext = nullptr;&#xA;&#xA;    AVStream* audioStream = nullptr;&#xA;    AVStream* videoStream = nullptr;&#xA;    AVCodec* audioCodec = nullptr;&#xA;    AVCodec* videoCodec = nullptr;&#xA;    AVCodecContext* audioCodecContext = nullptr;&#xA;    AVCodecContext* videoCodecContext = nullptr;&#xA;    vl::AudioSettings audioSettings;&#xA;    vl::VideoSettings videoSettings;&#xA;&#xA;    int audioIndex = -1;&#xA;    int videoIndex = -1;&#xA;&#xA;    SwsContext* swsContext = nullptr;&#xA;    std::vector frameBuffer;&#xA;    AVFrame* frame = av_frame_alloc();&#xA;    AVFrame* decoderFrame = av_frame_alloc();&#xA;&#xA;    AVPacket packet;&#xA;    cv::Mat mat;&#xA;&#xA;    vl::tools::MultimediaProcessing multimediaProcessing("rtsp://127.0.0.1:8080/stream", vl::configs::rtspStream, 0, vl::enums::EPixelFormat::ABGR);&#xA;&#xA;    // *** OPEN STREAM *** //&#xA;    if(avformat_open_input(&amp;formatContext, inputRtspAddress, nullptr, nullptr) &lt; 0)&#xA;    {&#xA;        std::cout &lt;&lt; "Failed to open input." &lt;&lt; std::endl;&#xA;        return EXIT_FAILURE;&#xA;    }&#xA;&#xA;    if(avformat_find_stream_info(formatContext, nullptr) &lt; 0)&#xA;    {&#xA;        std::cout &lt;&lt; "Failed to find stream info." &lt;&lt; std::endl;&#xA;        return EXIT_FAILURE;&#xA;    }&#xA;&#xA;    // *** FIND DECODER FOR BOTH AUDIO AND VIDEO STREAM *** //&#xA;    audioCodec = avcodec_find_decoder(AVCodecID::AV_CODEC_ID_AAC);&#xA;    videoCodec = avcodec_find_decoder(AVCodecID::AV_CODEC_ID_H264);&#xA;&#xA;    if(audioCodec == nullptr || videoCodec == nullptr)&#xA;    {&#xA;        std::cout &lt;&lt; "No AUDIO or VIDEO in stream." &lt;&lt; std::endl;&#xA;        return EXIT_FAILURE;&#xA;    }&#xA;&#xA;    // *** FIND STREAM FOR BOTH AUDIO AND VIDEO STREAM *** //&#xA;&#xA;    audioIndex = av_find_best_stream(formatContext, AVMEDIA_TYPE_AUDIO, -1, -1, &amp;audioCodec, 0);&#xA;    videoIndex = av_find_best_stream(formatContext, AVMEDIA_TYPE_VIDEO, -1, -1, &amp;videoCodec, 0);&#xA;&#xA;    if(audioIndex &lt; 0 || videoIndex &lt; 0)&#xA;    {&#xA;        std::cout &lt;&lt; "Failed to find AUDIO or VIDEO stream." &lt;&lt; std::endl;&#xA;        return EXIT_FAILURE;&#xA;    }&#xA;&#xA;    audioStream = formatContext->streams[audioIndex];&#xA;    videoStream = formatContext->streams[videoIndex];&#xA;&#xA;    // *** ALLOC CODEC CONTEXT FOR BOTH AUDIO AND VIDEO STREAM *** //&#xA;    audioCodecContext = avcodec_alloc_context3(audioCodec);&#xA;    videoCodecContext = avcodec_alloc_context3(videoCodec);&#xA;&#xA;    if(audioCodecContext == nullptr || videoCodecContext == nullptr)&#xA;    {&#xA;        std::cout &lt;&lt; "Can not allocate AUDIO or VIDEO context." &lt;&lt; std::endl;&#xA;        return EXIT_FAILURE;&#xA;    }&#xA;&#xA;    if(avcodec_parameters_to_context(audioCodecContext, formatContext->streams[audioIndex]->codecpar) &lt; 0 || avcodec_parameters_to_context(videoCodecContext, formatContext->streams[videoIndex]->codecpar) &lt; 0)&#xA;    {&#xA;        std::cout &lt;&lt; "Can not fill AUDIO or VIDEO codec context." &lt;&lt; std::endl;&#xA;        return EXIT_FAILURE;&#xA;    }&#xA;&#xA;    if(avcodec_open2(audioCodecContext, audioCodec, nullptr) &lt; 0 || avcodec_open2(videoCodecContext, videoCodec, nullptr) &lt; 0)&#xA;    {&#xA;        std::cout &lt;&lt; "Failed to open AUDIO codec" &lt;&lt; std::endl;&#xA;        return EXIT_FAILURE;&#xA;    }&#xA;&#xA;    // *** INITIALIZE MULTIMEDIA PROCESSING *** //&#xA;    std::vector<unsigned char="char"> extraData(audioStream->codecpar->extradata_size);&#xA;    std::copy_n(audioStream->codecpar->extradata, extraData.size(), extraData.begin());&#xA;&#xA;    audioSettings.sampleRate         = audioStream->codecpar->sample_rate,&#xA;    audioSettings.bitrate            = audioStream->codecpar->bit_rate,&#xA;    audioSettings.codec              = vl::enums::EAudioCodec::AAC,&#xA;    audioSettings.channels           = audioStream->codecpar->channels,&#xA;    audioSettings.bitsPerCodedSample = audioStream->codecpar->bits_per_coded_sample,&#xA;    audioSettings.bitsPerRawSample   = audioStream->codecpar->bits_per_raw_sample,&#xA;    audioSettings.blockAlign         = audioStream->codecpar->block_align,&#xA;    audioSettings.channelLayout      = audioStream->codecpar->channel_layout,&#xA;    audioSettings.format             = audioStream->codecpar->format,&#xA;    audioSettings.frameSize          = audioStream->codecpar->frame_size,&#xA;    audioSettings.codecExtraData     = std::move(extraData);&#xA;&#xA;    videoSettings.width              = 1920;&#xA;    videoSettings.height             = 1080;&#xA;    videoSettings.framerate          = 25;&#xA;    videoSettings.pixelFormat        = vl::enums::EPixelFormat::ARGB;&#xA;    videoSettings.bitrate            = 8000 * 1000;&#xA;    videoSettings.codec              = vl::enums::EVideoCodec::H264;&#xA;&#xA;    multimediaProcessing.initEncoder(videoSettings, audioSettings);&#xA;&#xA;    // *** INITIALIZE SWS CONTEXT *** //&#xA;    swsContext = sws_getCachedContext(nullptr, videoCodecContext->width, videoCodecContext->height, videoCodecContext->pix_fmt, videoCodecContext->width, videoCodecContext->height, AV_PIX_FMT_RGBA, SWS_FAST_BILINEAR, nullptr, nullptr, nullptr);&#xA;&#xA;    if (const auto inReturn = av_image_get_buffer_size(AV_PIX_FMT_RGBA, videoCodecContext->width, videoCodecContext->height, 1); inReturn > 0)&#xA;    {&#xA;        frameBuffer.reserve(inReturn);&#xA;    }&#xA;    else&#xA;    {&#xA;        std::cout &lt;&lt; "Can not get buffer size." &lt;&lt; std::endl;&#xA;        return EXIT_FAILURE;&#xA;    }&#xA;&#xA;    if (const auto inReturn = av_image_fill_arrays(frame->data, frame->linesize, frameBuffer.data(), AV_PIX_FMT_RGBA, videoCodecContext->width, videoCodecContext->height, 1); inReturn &lt; 0)&#xA;    {&#xA;        std::cout &lt;&lt; "Can not fill buffer arrays." &lt;&lt; std::endl;&#xA;        return EXIT_FAILURE;&#xA;    }&#xA;&#xA;    // *** MAIN LOOP *** //&#xA;    while(true)&#xA;    {&#xA;        // Return the next frame of a stream.&#xA;        if(av_read_frame(formatContext, &amp;packet) == 0)&#xA;        {&#xA;            if(packet.stream_index == videoIndex) // Check if it is video packet.&#xA;            {&#xA;                // Send packet to decoder.&#xA;                if(avcodec_send_packet(videoCodecContext, &amp;packet) == 0)&#xA;                {&#xA;                    int returnCode = avcodec_receive_frame(videoCodecContext, decoderFrame); // Get Frame from decoder.&#xA;&#xA;                    if (returnCode == 0) // Transform frame and send it to encoder. And re-stream that.&#xA;                    {&#xA;                        sws_scale(swsContext, decoderFrame->data, decoderFrame->linesize, 0, decoderFrame->height, frame->data, frame->linesize);&#xA;&#xA;                        mat = cv::Mat(videoCodecContext->height, videoCodecContext->width, CV_8UC4, frameBuffer.data(), frame->linesize[0]);&#xA;&#xA;                        cv::resize(mat, mat, cv::Size(1920, 1080), cv::INTER_NEAREST);&#xA;&#xA;                        multimediaProcessing.encode(mat.data, packet.dts, packet.dts, packet.flags == AV_PKT_FLAG_KEY); // Thise line sends cv::Mat to encoder and re-streams it.&#xA;&#xA;                        av_packet_unref(&amp;packet);&#xA;                    }&#xA;                    else if(returnCode == AVERROR(EAGAIN))&#xA;                    {&#xA;                        av_frame_unref(decoderFrame);&#xA;                        av_freep(decoderFrame);&#xA;                    }&#xA;                    else&#xA;                    {&#xA;                        av_frame_unref(decoderFrame);&#xA;                        av_freep(decoderFrame);&#xA;&#xA;                        std::cout &lt;&lt; "Error during decoding." &lt;&lt; std::endl;&#xA;                        return EXIT_FAILURE;&#xA;                    }&#xA;                }&#xA;            }&#xA;            else if(packet.stream_index == audioIndex) // Check if it is audio packet.&#xA;            {&#xA;                std::vector vectorPacket(packet.data, packet.data &#x2B; packet.size);&#xA;&#xA;                multimediaProcessing.addAudioPacket(vectorPacket, packet.dts, packet.dts);&#xA;            }&#xA;            else&#xA;            {&#xA;                av_packet_unref(&amp;packet);&#xA;            }&#xA;        }&#xA;        else&#xA;        {&#xA;            std::cout &lt;&lt; "Can not send video packet to decoder." &lt;&lt; std::endl;&#xA;            std::this_thread::sleep_for(std::chrono::seconds(1));&#xA;        }&#xA;    }&#xA;&#xA;    return EXIT_SUCCESS;&#xA;    }&#xA;</unsigned></string></iostream>

    &#xA;

    What does It do ?

    &#xA;

    It takes a single RTSP stream to decode its data so I can, for example, draw something to its frames or whatever, and then stream it under a different address.

    &#xA;

    Basically, I am opening the RTSP stream, check if it does contain both audio and video streams, and find a decoder for them. Then I create an encoder to which I will tell how the output stream should look like and that's it.

    &#xA;

    And this point I will create an endless loop Where I will read all packets coming from the input stream, then decode it does something to it and again encode it and re=stream it.

    &#xA;

    What is the issue ?

    &#xA;

    If you take a closer look I am sending both video and audio frame together with lastly received PTS and DTS contained in AVPacket, to the encoder.

    &#xA;

    The PTS and DTS from the point when I receive the first AVPacket looks for example like this.

    &#xA;

    IN AUDIO STREAM :

    &#xA;

    &#xA;

    -22783, -21759, -20735, -19711, -18687, -17663, -16639, -15615, -14591, -13567, -12543, -11519, -10495, -9471, -8447, -7423, -6399, -5375, -4351, -3327, -2303, -1279, -255, 769, 1793, 2817, 3841, 4865, 5889, 6913, 7937, 8961, 9985, 11009, 12033, 13057, 14081, 15105, 16129, 17153

    &#xA;

    &#xA;

    As you can see it is every time incremented by 1024 and that is a sample rate of the audio stream. Quite clear here.

    &#xA;

    IN VIDEO STREAM :

    &#xA;

    &#xA;

    86400, 90000, 93600, 97200, 100800, 104400, 108000, 111600, 115200, 118800, 122400, 126000, 129600, 133200, 136800, 140400, 144000, 147600, 151200, 154800, 158400, 162000, 165600

    &#xA;

    &#xA;

    As you can see it is every time incremented by 3600 but WHY ?. What this number actually mean ?

    &#xA;

    From what I can understand, those received PTS and DTS are for the following :

    &#xA;

    DTS should tell the encoder when it should start encoding the frame so the frame in time are in the correct order and not mishmashed.

    &#xA;

    PTS should say the correct time when the frame should be played/displayed in the output stream so the frame in time are in the correct order and not mishmashed.

    &#xA;

    What I am trying to achieve ?

    &#xA;

    As I said I need to restream a RTSP stream. I can not use PTS and DTS which comes from received AVPackets, because at some point it can happen that the input stream can randomly close and I need to open it again. The problem is that when I actually do it, then the PTS and DTS start to generate again from the minus values same as you could see in the samples. I CAN NOT send those "new" PTS and DTS to the encoder because they are now lower than the encoder/muxer expects.

    &#xA;

    I need to continually stream something (both audio and video), even it is a blank black screen or silent audio. And each frame the PTS and DTS should rise by a specific number. I need to figure out how the increment is calculated.

    &#xA;

    ----------------------------------

    &#xA;

    The final result should look like a mosaic of multiple input streams in a single output stream. A single input stream (main) has both audio and video and the rest (side) has just video. Some of those streams can randomly close in time and I need to ensure that it will be back again once it is possible.

    &#xA;

  • Invalid data stream in media could not be discarded by FFMPEG. Why is it staying and how to discard it ?

    5 décembre 2020, par Link-akro

    I have downloaded a [short media][1] i intend to convert then i will use the result as basis to practice and test any and all FFMPEG commands i learn or use later.

    &#xA;

    That video seems to have an unknown invalid stream which never disappears no matter everything i tried to discard it. When i try to work with it later i get various problems like missing codec or no stream which is not the focus here but the reason why i got stubborn to remove the things i cannot deal with.

    &#xA;

    The following probing prints a warning in yellow color on last row.

    &#xA;

     > ffprobe -hide_banner -show_streams Movie_Countdown-youtube_I1vMKZ1kvg0.mov&#xA;&#xA;Input #0, mov,mp4,m4a,3gp,3g2,mj2, from &#x27;Movie_Countdown-youtube_I1vMKZ1kvg0.mov&#x27;:&#xA;  Metadata:&#xA;    major_brand     : qt&#xA;    minor_version   : 537199360&#xA;    compatible_brands: qt&#xA;    creation_time   : 2015-05-20T13:45:55.000000Z&#xA;  Duration: 00:00:10.00, start: 0.000000, bitrate: 11474 kb/s&#xA;    Stream #0:0(eng): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709), 1920x1080, 9930 kb/s, SAR 1:1 DAR 16:9, 25 fps, 25 tbr, 25 tbn, 50 tbc (default)&#xA;    Metadata:&#xA;      creation_time   : 2015-05-20T13:45:55.000000Z&#xA;      handler_name    : Apple Video Media Handler&#xA;      encoder         : H.264&#xA;      timecode        : 00:00:00:00&#xA;    Stream #0:1(eng): Audio: pcm_s16le (sowt / 0x74776F73), 48000 Hz, stereo, s16, 1536 kb/s (default)&#xA;    Metadata:&#xA;      creation_time   : 2015-05-20T13:45:56.000000Z&#xA;      handler_name    : Apple Sound Media Handler&#xA;      timecode        : 00:00:00:00&#xA;    Stream #0:2(eng): Data: none (tmcd / 0x64636D74), 0 kb/s (default)&#xA;    Metadata:&#xA;      creation_time   : 2015-05-20T13:46:11.000000Z&#xA;      handler_name    : Time Code Media Handler&#xA;      timecode        : 00:00:00:00&#xA;Unsupported codec with id 0 for input stream 2&#xA;

    &#xA;

    Below the streams output. I split the text so you see the warning without searching in the middle.

    &#xA;

    [STREAM]&#xA;index=0&#xA;codec_name=h264&#xA;codec_long_name=H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10&#xA;profile=Main&#xA;codec_type=video&#xA;codec_time_base=1/50&#xA;codec_tag_string=avc1&#xA;codec_tag=0x31637661&#xA;width=1920&#xA;height=1080&#xA;coded_width=1920&#xA;coded_height=1088&#xA;closed_captions=0&#xA;has_b_frames=0&#xA;sample_aspect_ratio=1:1&#xA;display_aspect_ratio=16:9&#xA;pix_fmt=yuv420p&#xA;level=40&#xA;color_range=tv&#xA;color_space=bt709&#xA;color_transfer=bt709&#xA;color_primaries=bt709&#xA;chroma_location=left&#xA;field_order=unknown&#xA;timecode=N/A&#xA;refs=1&#xA;is_avc=true&#xA;nal_length_size=4&#xA;id=N/A&#xA;r_frame_rate=25/1&#xA;avg_frame_rate=25/1&#xA;time_base=1/25&#xA;start_pts=0&#xA;start_time=0.000000&#xA;duration_ts=250&#xA;duration=10.000000&#xA;bit_rate=9930739&#xA;max_bit_rate=N/A&#xA;bits_per_raw_sample=8&#xA;nb_frames=250&#xA;nb_read_frames=N/A&#xA;nb_read_packets=N/A&#xA;DISPOSITION:default=1&#xA;DISPOSITION:dub=0&#xA;DISPOSITION:original=0&#xA;DISPOSITION:comment=0&#xA;DISPOSITION:lyrics=0&#xA;DISPOSITION:karaoke=0&#xA;DISPOSITION:forced=0&#xA;DISPOSITION:hearing_impaired=0&#xA;DISPOSITION:visual_impaired=0&#xA;DISPOSITION:clean_effects=0&#xA;DISPOSITION:attached_pic=0&#xA;DISPOSITION:timed_thumbnails=0&#xA;TAG:creation_time=2015-05-20T13:45:55.000000Z&#xA;TAG:language=eng&#xA;TAG:handler_name=Apple Video Media Handler&#xA;TAG:encoder=H.264&#xA;TAG:timecode=00:00:00:00&#xA;[/STREAM]&#xA;[STREAM]&#xA;index=1&#xA;codec_name=pcm_s16le&#xA;codec_long_name=PCM signed 16-bit little-endian&#xA;profile=unknown&#xA;codec_type=audio&#xA;codec_time_base=1/48000&#xA;codec_tag_string=sowt&#xA;codec_tag=0x74776f73&#xA;sample_fmt=s16&#xA;sample_rate=48000&#xA;channels=2&#xA;channel_layout=stereo&#xA;bits_per_sample=16&#xA;id=N/A&#xA;r_frame_rate=0/0&#xA;avg_frame_rate=0/0&#xA;time_base=1/48000&#xA;start_pts=0&#xA;start_time=0.000000&#xA;duration_ts=480000&#xA;duration=10.000000&#xA;bit_rate=1536000&#xA;max_bit_rate=N/A&#xA;bits_per_raw_sample=N/A&#xA;nb_frames=480000&#xA;nb_read_frames=N/A&#xA;nb_read_packets=N/A&#xA;DISPOSITION:default=1&#xA;DISPOSITION:dub=0&#xA;DISPOSITION:original=0&#xA;DISPOSITION:comment=0&#xA;DISPOSITION:lyrics=0&#xA;DISPOSITION:karaoke=0&#xA;DISPOSITION:forced=0&#xA;DISPOSITION:hearing_impaired=0&#xA;DISPOSITION:visual_impaired=0&#xA;DISPOSITION:clean_effects=0&#xA;DISPOSITION:attached_pic=0&#xA;DISPOSITION:timed_thumbnails=0&#xA;TAG:creation_time=2015-05-20T13:45:56.000000Z&#xA;TAG:language=eng&#xA;TAG:handler_name=Apple Sound Media Handler&#xA;TAG:timecode=00:00:00:00&#xA;[/STREAM]&#xA;[STREAM]&#xA;index=2&#xA;codec_name=unknown&#xA;codec_long_name=unknown&#xA;profile=unknown&#xA;codec_type=data&#xA;codec_tag_string=tmcd&#xA;codec_tag=0x64636d74&#xA;id=N/A&#xA;r_frame_rate=0/0&#xA;avg_frame_rate=25/1&#xA;time_base=1/25&#xA;start_pts=0&#xA;start_time=0.000000&#xA;duration_ts=250&#xA;duration=10.000000&#xA;bit_rate=3&#xA;max_bit_rate=N/A&#xA;bits_per_raw_sample=N/A&#xA;nb_frames=1&#xA;nb_read_frames=N/A&#xA;nb_read_packets=N/A&#xA;DISPOSITION:default=1&#xA;DISPOSITION:dub=0&#xA;DISPOSITION:original=0&#xA;DISPOSITION:comment=0&#xA;DISPOSITION:lyrics=0&#xA;DISPOSITION:karaoke=0&#xA;DISPOSITION:forced=0&#xA;DISPOSITION:hearing_impaired=0&#xA;DISPOSITION:visual_impaired=0&#xA;DISPOSITION:clean_effects=0&#xA;DISPOSITION:attached_pic=0&#xA;DISPOSITION:timed_thumbnails=0&#xA;TAG:creation_time=2015-05-20T13:46:11.000000Z&#xA;TAG:language=eng&#xA;TAG:handler_name=Time Code Media Handler&#xA;TAG:timecode=00:00:00:00&#xA;[/STREAM]&#xA;

    &#xA;

    I scaled it down and recoded it for starters and i tried to discard the data stream with -dn and failed other methods i will mention at the end.&#xA;The output so far suggests that discarding should have worked since alternative datas are 0kB and no stream 2 is listed.

    &#xA;

     > ffmpeg -hide_banner -dn -i C:\Users\admin-dix\Downloads\Movie_Countdown-youtube_I1vMKZ1kvg0.mov -vf "scale=h=450:w=800" -f mp4 -c:a aac -c:v libx264 mov_countdown.mp4&#xA;&#xA;Output #0, mp4, to &#x27;mov_countdown.mp4&#x27;:&#xA;  Metadata:&#xA;    major_brand     : qt&#xA;    minor_version   : 537199360&#xA;    compatible_brands: qt&#xA;    encoder         : Lavf58.45.100&#xA;    Stream #0:0(eng): Video: h264 (libx264) (avc1 / 0x31637661), yuv420p(progressive), 800x450 [SAR 1:1 DAR 16:9], q=-1--1, 0.04 fps, 12800 tbn, 25 tbc (default)&#xA;    Metadata:&#xA;      creation_time   : 2015-05-20T13:45:55.000000Z&#xA;      handler_name    : Apple Video Media Handler&#xA;      timecode        : 00:00:00:00&#xA;      encoder         : Lavc58.91.100 libx264&#xA;    Side data:&#xA;      cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A&#xA;    Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s (default)&#xA;    Metadata:&#xA;      creation_time   : 2015-05-20T13:45:56.000000Z&#xA;      handler_name    : Apple Sound Media Handler&#xA;      timecode        : 00:00:00:00&#xA;      encoder         : Lavc58.91.100 aac&#xA;frame=  250 fps= 43 q=-1.0 Lsize=     342kB time=00:00:10.00 bitrate= 280.1kbits/s speed= 1.7x&#xA;video:175kB audio:159kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 2.710857%&#xA;

    &#xA;

    Then ffprobe disagrees, there is still the stream and the warning.

    &#xA;

    ffprobe mov_countdown.mp4&#xA;&#xA;Input #0, mov,mp4,m4a,3gp,3g2,mj2, from &#x27;mov_countdown.mp4&#x27;:&#xA;  Metadata:&#xA;    major_brand     : isom&#xA;    minor_version   : 512&#xA;    compatible_brands: isomiso2avc1mp41&#xA;    encoder         : Lavf58.45.100&#xA;  Duration: 00:00:10.02, start: 0.000000, bitrate: 279 kb/s&#xA;    Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 800x450 [SAR 1:1 DAR 16:9], 142 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc (default)&#xA;    Metadata:&#xA;      handler_name    : Apple Video Media Handler&#xA;      timecode        : 00:00:00:00&#xA;    Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 129 kb/s (default)&#xA;    Metadata:&#xA;      handler_name    : Apple Sound Media Handler&#xA;    Stream #0:2(eng): Data: none (tmcd / 0x64636D74), 0 kb/s&#xA;    Metadata:&#xA;      handler_name    : Apple Video Media Handler&#xA;      timecode        : 00:00:00:00&#xA;Unsupported codec with id 0 for input stream 2&#xA;

    &#xA;

    I tried negative mapping as per this answer -map 0:d which failed. I did not understand -discard option as ffmpeg documentation refers to from the -vn,-an,-dn entries as it does not specify a stream.

    &#xA;

    Why does it do that and how can i remove that stream i do not know and do not want to care about in future tests ?

    &#xA;

    [1] : Clean Retro Movie Countdown - YouTube from Philippe Moesch https://www.youtube.com/watch?v=I1vMKZ1kvg0

    &#xA;

  • How to take screenshots of streamers using the Twitch API

    10 décembre 2020, par oo92

    My goal is to create a dataset of gameplays on Twitch using the API. How I want to do it is this :

    &#xA;

      &#xA;
    1. Get a list of live streams using the API.
    2. &#xA;

    3. Use streamlink and ffmpeg on Python to take the screenshots through the Stream source
    4. &#xA;

    &#xA;

    To get the streams, I have the following code thanks to a SO user :

    &#xA;

    from twitch import TwitchClient&#xA;&#xA;client = TwitchClient(client_id=&#x27;<my client="client">&#x27;)&#xA;streams = client.streams.get_live_streams(limit=100)&#xA;&#xA;print(streams)&#xA;</my>

    &#xA;

    The output is this. Its a lot larger, I just made it shorter... :

    &#xA;

    [{&#x27;id&#x27;: 40889579422, &#x27;game&#x27;: &#x27;Among Us&#x27;, &#x27;broadcast_platform&#x27;: &#x27;live&#x27;, &#x27;community_id&#x27;: &#x27;&#x27;, &#x27;community_ids&#x27;: [], &#x27;viewers&#x27;: 74594, &#x27;video_height&#x27;: 1080, &#x27;average_fps&#x27;: 60, &#x27;delay&#x27;: 0, &#x27;created_at&#x27;: datetime.datetime(2020, 12, 9, 23, 53, 34), &#x27;is_playlist&#x27;: False, &#x27;stream_type&#x27;: &#x27;live&#x27;, &#x27;preview&#x27;: {&#x27;small&#x27;: &#x27;https://static-cdn.jtvnw.net/previews-ttv/live_user_sykkuno-80x45.jpg&#x27;, &#x27;medium&#x27;: &#x27;https://static-cdn.jtvnw.net/previews-ttv/live_user_sykkuno-320x180.jpg&#x27;, &#x27;large&#x27;: &#x27;https://static-cdn.jtvnw.net/previews-ttv/live_user_sykkuno-640x360.jpg&#x27;, &#x27;template&#x27;: &#x27;https://static-cdn.jtvnw.net/previews-ttv/live_user_sykkuno-{width}x{height}.jpg&#x27;}, &#x27;channel&#x27;: {&#x27;mature&#x27;: False, &#x27;status&#x27;: &#x27;amongus at 4 !!&#x27;, &#x27;broadcaster_language&#x27;: &#x27;en&#x27;, &#x27;broadcaster_software&#x27;: &#x27;&#x27;, &#x27;display_name&#x27;: &#x27;Sykkuno&#x27;, &#x27;game&#x27;: &#x27;Among Us&#x27;, &#x27;language&#x27;: &#x27;en&#x27;, &#x27;id&#x27;: 26154978, &#x27;name&#x27;: &#x27;sykkuno&#x27;, &#x27;created_at&#x27;: datetime.datetime(2011, 11, 15, 1, 29, 29, 140794), &#x27;updated_at&#x27;: datetime.datetime(2020, 12, 10, 0, 35, 50, 916363), &#x27;partner&#x27;: True, &#x27;logo&#x27;: &#x27;https://static-cdn.jtvnw.net/jtv_user_pictures/sykkuno-profile_image-6ab1e70e07e29e9b-300x300.jpeg&#x27;, &#x27;video_banner&#x27;: &#x27;https://static-cdn.jtvnw.net/jtv_user_pictures/4b654ce5-58dc-4fa6-b77c-7250bb2d5269-channel_offline_image-1920x1080.png&#x27;, &#x27;profile_banner&#x27;: &#x27;https://static-cdn.jtvnw.net/jtv_user_pictures/1caee146-3323-4d45-9907-96c20c224d3e-profile_banner-480.png&#x27;, &#x27;profile_banner_background_color&#x27;: &#x27;&#x27;, &#x27;url&#x27;: &#x27;https://www.twitch.tv/sykkuno&#x27;, &#x27;views&#x27;: 23590965, &#x27;followers&#x27;: 1928724, &#x27;broadcaster_type&#x27;: &#x27;&#x27;, &#x27;description&#x27;: &#x27;Hi ! &#x27;, &#x27;private_video&#x27;: False, &#x27;privacy_options_enabled&#x27;: False}}, ... &#xA;

    &#xA;

    First, I want to know how I can iterate through the JSON to get the channel name using the id. I tried to do it on my own but it said that it isn't subscriptable.

    &#xA;

    Second, I have the following code that tries to use ffmpeg to get a screenshot of the stream through its source :

    &#xA;

    import streamlink, os&#xA;&#xA;# This code connects to the streamer&#x27;s source&#xA;# Get the Twitch API to work so you can add the streamer&#x27;s name at the end of the link&#xA;username = &#x27;Sykkuno&#x27;&#xA;streams = streamlink.streams(&#x27;http://twitch.tv/&#x27; &#x2B; username)&#xA;&#xA;# Stream source&#xA;stream = streams["best"].url&#xA;&#xA;# Directory where the screenshots will be saved&#xA;dir_path = os.getcwd() &#x2B; &#x27;/&#x27; &#x2B; username&#xA;&#xA;# number of streamers&#xA;streamers = 1&#xA;&#xA;os.system(&#x27;ffmpeg -i &#x27; &#x2B; stream &#x2B;&#x27; -r 0.5 -f image2 ${dir}/output_%09d.jpg&#x27;)&#xA;

    &#xA;

    But that is throwing the following error :

    &#xA;

    ffmpeg version 4.1.3-0ppa1~18.04 Copyright (c) 2000-2019 the FFmpeg developers&#xA;  built with gcc 7 (Ubuntu 7.3.0-27ubuntu1~18.04)&#xA;  configuration: --prefix=/usr --extra-version=&#x27;0ppa1~18.04&#x27; --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opengl --enable-sdl2 --enable-nonfree --enable-libfdk-aac --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared&#xA;  libavutil      56. 22.100 / 56. 22.100&#xA;  libavcodec     58. 35.100 / 58. 35.100&#xA;  libavformat    58. 20.100 / 58. 20.100&#xA;  libavdevice    58.  5.100 / 58.  5.100&#xA;  libavfilter     7. 40.101 /  7. 40.101&#xA;  libavresample   4.  0.  0 /  4.  0.  0&#xA;  libswscale      5.  3.100 /  5.  3.100&#xA;  libswresample   3.  3.100 /  3.  3.100&#xA;  libpostproc    55.  3.100 / 55.  3.100&#xA;[hls,applehttp @ 0x557212854940] Opening &#x27;https://video-edge-c2a360.yto01.abs.hls.ttvnw.net/v1/segment/CuAErHgNDEVK3cqjkRZLcz4El99YD2ZSy9tgtjc3ZTrPuN4584-GY3DKYO3MFCBt9M3v8_7IfHAlLvHeUn2wq4d-VC7u4Zv2-k1Bee9IPmIXbFQLZFKrYiT98OTzFMDaElsEZ9Sr4MXz6FoAC1yXhhZ0MYahZVnZa1Tuqnn217nN_rN8wr7kdScBIir_Uo1s2C_I8_54mi2uzdgxB9AYj0a0kG2UtdPkUVA6Qc7XIZ0nUhEeObEf80N0uW9ZU6WHpO3V6G9RD0VkmwUexDWk9MaLy1NJuvLSzRaMfOmKxhrzn3UDoY4CrQN11KOnHYCiCOfvhZmMKzSqtiA8YP0Q9iS03eZZhPQ3WxBHWhd6VeZ0btNeeoudGX73EBIj4ujZnKWKfPiN8K_HLj5FZWqQ5m_4Q1llQlnSAfmhzXR9PHAkz8nxRVcFR-tFokGzFEfkZGHngPNz9boLmo4KHx6404rocPUcXbTHkYsWXZwFC356AhfrNn6x0JYHGfcDpRsEFebLQljEpCyhnNOHFEf9b7Ipeiy521cCupzoEz1uMrzW77h9FJwn0GwvY3jp2KwRXJMvArYwiUHccBmfW7ZDLO9vH7eJGUnAzoy586KMSPLVeLxWMWRDfKkAcI8vYXOIuxNb_MZKm2O_dcoFrDDta5TZn-MLjFquT47P9NbXxlTTJfimlYyMG17SPoW3KJVtAJmjoj0GZ1ehftLJWz1Qgd8zmg40u4g8fz867eCHW_Tiv65yd6qJZD-_bD3G916fm3KeA9bPyhalTD99CWhQL7f0apCfX_6IiQElgPT6kOrFI-ISEG4GdhIpFi4ubzSx29pm7H4aDIXx6BAI5ziHVMPbrg.ts&#x27; for reading&#xA;[hls,applehttp @ 0x557212854940] Opening &#x27;https://video-edge-c2a360.yto01.abs.hls.ttvnw.net/v1/segment/CuIECWLarz2I5hNCtGLSTDXbCIgahI91KOHXVmPHddzZediyiVbcicZpGakO99CJp1cK_6OnmOKBzZ3sn3KogNyPVRqSy32IpanlyPPUTz23TojfR5DTmJa3zampOzVMfETvvPEpj58-kGhQeQQGtK1zLV2h465RElCLkmc7SeWbXEZ5j6IQ38OVFZ0vdcMHVTNPtJaY7509bE196-9-5YYFiET_-kdkS2X6_lhVQBZrq45PBxApTzeLkDx9ZtGQx78dLr_tZepww_uVnJTwxI_TA3tU8z5_w8ml6rh0GK1W6lTlvuDkPKAwIDLvG736MtbPGz9cFPoRAFQxD3QSwAM-bO1grvWlNsOUDUYLXLNjuejmz8xmRpeE0pqJYxUboRZpxrPXTi52HcX8lpGT4Lx2z6hJcoi9npQttK58HDSHQ3cYH3rlNsYV_RlZ3F-u-fZSn8Em67-vAYeXAMaBe9xxv0Zu2n1TrdPICMyGmk-VgLK788IeDhxqM441GONGLxo6AF8RE5_OawTf9n_MVzImsX4LMn0oN8e8w6mjk7YDuNdA4mEl99Erg8xMdX6Q3fDYTdStaC-zQwXgMctfGpIsUpp91BtRBPMynFCxZ8fZB7NvGFNZTYWDvCZjisiwzs0N1pDdDM_Fkj3i46_Ou105z348PLHRA28Dt1qgn_NjzwRNoaowFx7PxQ-X2zRpAhwNcqaTOHYh5NYZHToVE16WiOe9HzVs_I_3Wqu44bypEsGrhxYhgXSGfvO757iTbErZHmkidsBF2BET5j3JeIifr4fJooalAKc_5uiSPMCGSTtV9hIQX5mQWJudg9UsMRp1AWVrnBoMQPAhy1UwBDtAOrBs.ts&#x27; for reading&#xA;Input #0, hls,applehttp, from &#x27;https://video-weaver.yto01.hls.ttvnw.net/v1/playlist/CvADco9ZO_szpL7RVLVI3U6zl4IMo2uaUBvZTWAyEOKETN-SxI3m3hLLxpmCfz06rlyCGCPimEbk28kKPSbVYtMThiZFRtLxnrdpLr5DWBQwbpIStPQwMetU4Z04Mkm3nEWplL8hpn69Cmd_eWSdI1yHubK_sRL-n1ml5akAEWWGkS0OgVRQTTsYv4RpkbeWc8wrr3DsDBDfyrxciGSZevnStZOLwg-tNuNu3VNugLigNG1HMsNdxoJGO6wLyO-6FL5EQidOiSw2THSibAvADAWMVOxNX2z39d-nJwbVprbWFnox_lDlh-y88uhjj_MpU6OwkXP9vgrBDEmKjtRbYsIN5N94-8pDFEB3yIYk10vUiuod1yfqztVCqWo5m9r48uINP1CD-Bwgybo6K7Oko-TUjMj43GqAu0mmPtkgPFO69LpQQMifZTn_XbVQ5UUfoCwyl-ljObfRE51aCvZP_dOTsUyqi_JRE8h-C3306aW1ISXwCs3YpnjDxJv6yKyWTktBvsN5NWMVzJg-_-MAtTmoy-w2ppbbOozLzyrGF4zfCetaHLmHtbsKe1Ed1nndJg9b6T7v-87ExrI0eQwRjH3gmBTgqu_peS5oQGBaDOe4QSGMNFgf8lQfuqvFH-miXgpk8RytdorzT7wB05iX7c3bhBIQ3FvvjNIal3IgvyxKatZs4BoMW_P_CuyZOUJs2_Yr.m3u8&#x27;:&#xA;  Duration: N/A, start: 60.000000, bitrate: N/A&#xA;  Program 0 &#xA;    Metadata:&#xA;      variant_bitrate : 0&#xA;    Stream #0:0: Audio: aac (LC) ([15][0][0][0] / 0x000F), 44100 Hz, stereo, fltp&#xA;    Metadata:&#xA;      variant_bitrate : 0&#xA;    Stream #0:1: Video: h264 (Main) ([27][0][0][0] / 0x001B), yuv420p(tv, unknown/bt709/unknown), 1920x1080, 29.97 tbr, 90k tbn, 2k tbc&#xA;    Metadata:&#xA;      variant_bitrate : 0&#xA;    Stream #0:2: Data: timed_id3 (ID3  / 0x20334449)&#xA;    Metadata:&#xA;      variant_bitrate : 0&#xA;Stream mapping:&#xA;  Stream #0:1 -> #0:0 (h264 (native) -> mjpeg (native))&#xA;Press [q] to stop, [?] for help&#xA;[swscaler @ 0x557213e262c0] deprecated pixel format used, make sure you did set range correctly&#xA;Output #0, image2, to &#x27;/output_%09d.jpg&#x27;:&#xA;  Metadata:&#xA;    encoder         : Lavf58.20.100&#xA;    Stream #0:0: Video: mjpeg, yuvj420p(pc), 1920x1080, q=2-31, 200 kb/s, 0.50 fps, 0.50 tbn, 0.50 tbc&#xA;    Metadata:&#xA;      variant_bitrate : 0&#xA;      encoder         : Lavc58.35.100 mjpeg&#xA;    Side data:&#xA;      cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: -1&#xA;[image2 @ 0x557213012040] Could not open file : /output_000000001.jpg&#xA;av_interleaved_write_frame(): Input/output error&#xA;frame=    1 fps=0.0 q=7.5 Lsize=N/A time=00:00:02.00 bitrate=N/A speed=27.7x    &#xA;video:46kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown&#xA;Conversion failed!&#xA;

    &#xA;