Recherche avancée

Médias (2)

Mot : - Tags -/documentation

Autres articles (38)

  • Support audio et vidéo HTML5

    10 avril 2011

    MediaSPIP utilise les balises HTML5 video et audio pour la lecture de documents multimedia en profitant des dernières innovations du W3C supportées par les navigateurs modernes.
    Pour les navigateurs plus anciens, le lecteur flash Flowplayer est utilisé.
    Le lecteur HTML5 utilisé a été spécifiquement créé pour MediaSPIP : il est complètement modifiable graphiquement pour correspondre à un thème choisi.
    Ces technologies permettent de distribuer vidéo et son à la fois sur des ordinateurs conventionnels (...)

  • HTML5 audio and video support

    13 avril 2011, par

    MediaSPIP 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 (...)

  • De l’upload à la vidéo finale [version standalone]

    31 janvier 2010, par

    Le chemin d’un document audio ou vidéo dans SPIPMotion est divisé en trois étapes distinctes.
    Upload et récupération d’informations de la vidéo source
    Dans un premier temps, il est nécessaire de créer un article SPIP et de lui joindre le document vidéo "source".
    Au moment où ce document est joint à l’article, deux actions supplémentaires au comportement normal sont exécutées : La récupération des informations techniques des flux audio et video du fichier ; La génération d’une vignette : extraction d’une (...)

Sur d’autres sites (4374)

  • Segmentation fault on debian 9 when decoding audio with ffmpeg and libopus

    27 août 2021, par Ramil Dautov

    I wrote the program that takes as an input some .opus file, decodes it using libavcodec and libopus and then plays it using SDL2. Program works on Windows 10 and Ubuntu 18.04, however it crashes with the segmentation fault on Debian 9.

    


    I've tried to update libavcodec and libopus libraries, tried to compile using clang and gcc - nothing helped.

    


    Address sanitizer shows that stack overflow happens :

    


    ASAN:DEADLYSIGNAL
=================================================================
==12167==ERROR: AddressSanitizer: stack-overflow on address 0x2b3e74c81ff8 (pc 0x2b3e7a098803 bp 0x2b3e74c82690 sp 0x2b3e74c81eb0 T2)
    #0 0x2b3e7a098802 in quant_all_bands celt/bands.c:1403
    #1 0x2b3e7a0a2a37 in celt_decode_with_ec celt/celt_decoder.c:1083
    #2 0x2b3e7a0c8afb in opus_decode_frame src/opus_decoder.c:518
    #3 0x2b3e7a0c9e40 in opus_decode_native src/opus_decoder.c:721
    #4 0x2b3e7a0d33f3 in opus_multistream_decode_native src/opus_multistream_decoder.c:253
    #5 0x2b3e7a0d37a8 in opus_multistream_decode src/opus_multistream_decoder.c:398
    #6 0x2b3e760ad83c  (/usr/lib/x86_64-linux-gnu/libavcodec.so.57+0x43583c)
    #7 0x2b3e75e4ca27  (/usr/lib/x86_64-linux-gnu/libavcodec.so.57+0x1d4a27)
    #8 0x2b3e75e4f62a in avcodec_send_packet (/usr/lib/x86_64-linux-gnu/libavcodec.so.57+0x1d762a)
    #9 0x2b3e75e4f9e6  (/usr/lib/x86_64-linux-gnu/libavcodec.so.57+0x1d79e6)
    #10 0x55ef09511882 in decode(AVCodecContext*, AVPacket*, unsigned char*, int) /home/ram/my/player3/speaker.cpp:296
    #11 0x55ef09511626 in fillBuffer(AVCodecContext*, unsigned char*, int) /home/ram/my/player3/speaker.cpp:251
    #12 0x55ef09511294 in process(AVCodecContext*, unsigned char*, int) /home/ram/my/player3/speaker.cpp:194
    #13 0x55ef095105b9 in audio_callback(void*, unsigned char*, int) /home/ram/my/player3/speaker.cpp:69
    #14 0x2b3e7815cc31  (/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0+0x1fc31)
    #15 0x2b3e781bcf8b  (/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0+0x7ff8b)
    #16 0x2b3e7820c6c8  (/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0+0xcf6c8)
    #17 0x2b3e77be74a3 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x74a3)
    #18 0x2b3e7940ed0e in __clone (/lib/x86_64-linux-gnu/libc.so.6+0xe8d0e)

SUMMARY: AddressSanitizer: stack-overflow celt/bands.c:1403 in quant_all_bands
Thread T2 (SDLAudioDev2) created by T0 here:
    #0 0x2b3e74d0df59 in __interceptor_pthread_create (/usr/lib/x86_64-linux-gnu/libasan.so.3+0x30f59)
    #1 0x2b3e7820c732  (/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0+0xcf732)



    


    I also tried to increase stack size using ulimit -s unlimited and tried to increase stack size for the thread that starts decoding, didn't work.

    


    In main.cpp file I have this :

    


    #include <iostream>&#xA;#include <memory>&#xA;#include <mutex>&#xA;#include "speaker.h"&#xA;#include "SDL2/SDL.h"&#xA;&#xA;extern "C"{&#xA;#include <libavutil></libavutil>opt.h>&#xA;#include <libavcodec></libavcodec>avcodec.h>&#xA;#include <libavformat></libavformat>avformat.h>&#xA;#include <libswresample></libswresample>swresample.h>&#xA;}&#xA;&#xA;static int decode_audio_file(const char* path) {&#xA;    &#xA;    av_register_all();&#xA;&#xA;    // get format from audio file&#xA;    AVFormatContext* format = avformat_alloc_context();&#xA;    if (avformat_open_input(&amp;format, path, NULL, NULL) != 0) {&#xA;        std::cout &lt;&lt; "Could not open file" &lt;&lt; std::endl;&#xA;        return -1;&#xA;    }&#xA;    if (avformat_find_stream_info(format, NULL) &lt; 0) {&#xA;        std::cout &lt;&lt; "Could not retrieve stream info from file" &lt;&lt; std::endl;&#xA;        return -1;&#xA;    }&#xA;&#xA;    // Find the index of the first audio stream&#xA;    int stream_index =- 1;&#xA;    for (int i=0; i&lt; format->nb_streams; i&#x2B;&#x2B;) {&#xA;        if (format->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {&#xA;            stream_index = i;&#xA;            break;&#xA;        }&#xA;    }&#xA;    if (stream_index == -1) {&#xA;        std::cout &lt;&lt; "Could not retrieve audio stream from file" &lt;&lt; std::endl;&#xA;        return -1;&#xA;    }&#xA;    AVStream* stream = format->streams[stream_index];&#xA;&#xA;    // Initialize speaker&#xA;    init_Speaker("OPUS",&#xA;                  48000,&#xA;                  2,&#xA;                  15,&#xA;                  3,&#xA;                  av_get_channel_layout("stereo"),&#xA;                  av_get_sample_fmt("s16"));&#xA;&#xA;    // prepare to read data&#xA;    AVPacket* packet;&#xA;    packet = av_packet_alloc();&#xA;    av_init_packet(packet);&#xA;&#xA;    // iterate through frames&#xA;    while (av_read_frame(format, packet) >= 0) {&#xA;        play(packet->data, packet->size, std::chrono::microseconds{packet->pts},&#xA;                std::chrono::microseconds{packet->dts});&#xA;        av_packet_unref(packet);&#xA;    }&#xA;&#xA;    // clean up&#xA;    avformat_free_context(format);&#xA;    close_Speaker();&#xA;&#xA;    // success&#xA;    return 0;&#xA;}&#xA;&#xA;int main(int argc, char const *argv[]) {&#xA;    // check parameters&#xA;    if (argc &lt; 2) {&#xA;        std::cout &lt;&lt; "Please provide the path to an audio file as first command-line argument.\n";&#xA;        return -1;&#xA;    }&#xA;&#xA;    // Init Audio&#xA;    SDL_Init(SDL_INIT_AUDIO);&#xA;&#xA;    // decode data&#xA;    if (decode_audio_file(argv[1]) != 0) {&#xA;        return -1;&#xA;    }&#xA;&#xA;    std::cout &lt;&lt; "Finish" &lt;&lt; std::endl;&#xA;    return 0;&#xA;}&#xA;&#xA;</mutex></memory></iostream>

    &#xA;

    In speaker.cpp :

    &#xA;

    #include "speaker.h"&#xA;#include "pthread.h"&#xA;#include "avcodec.h"&#xA;#include "common.h"&#xA;#include <iostream>&#xA;&#xA;extern "C"&#xA;{&#xA;#include <libswresample></libswresample>swresample.h>&#xA;#include <libavutil></libavutil>hwcontext.h>&#xA;}&#xA;&#xA;using std::chrono::microseconds;&#xA;&#xA;SDL_AudioDeviceID m_id;&#xA;&#xA;AVCodecParserContext *parser = nullptr;&#xA;&#xA;//&#xA;constexpr static auto buffer_size{1024}; // 2048&#xA;constexpr static auto buffer_max_size{AVCODEC_MAX_AUDIO_FRAME_SIZE * 4};&#xA;uint32_t m_samplerate;&#xA;uint32_t m_queue_limit;&#xA;uint32_t m_queue_dropfactor;&#xA;int64_t m_channel_layout;&#xA;AVSampleFormat m_device_format;&#xA;AVCodecID audio_codec_id{AV_CODEC_ID_NONE};&#xA;AVCodecContext* adecoder;&#xA;&#xA;player::PacketQueue queue(0, true); &#xA;&#xA;&#xA;static uint8_t* buf = nullptr;&#xA;uint32_t absize{};&#xA;uint32_t abpos{};&#xA;int32_t max_decoder_size{};&#xA;// need a converter?&#xA;uint8_t* convbuf{};&#xA;SwrContext* swrctx{};&#xA;int32_t sframes{};&#xA;AVCodec* codec{};&#xA;&#xA;uint8_t * audio_buffer_init() {&#xA;    if(buf == nullptr) {&#xA;        buf = (uint8_t*) malloc(buffer_max_size);&#xA;        if(buf == nullptr) {&#xA;            return nullptr;&#xA;        }&#xA;    }&#xA;    return buf;&#xA;}&#xA;&#xA;void audio_callback(void* userdata, uint8_t* stream, int len) {&#xA;    AVCodecContext* decoder = (AVCodecContext*)userdata;&#xA;    process(decoder, stream, len);&#xA;};&#xA;&#xA;void init_Speaker(const std::string&amp; codecName,&#xA;                 int32_t samplerate,&#xA;                 uint8_t channels,&#xA;                 uint32_t queue_limit,&#xA;                 uint32_t queue_dropfactor,&#xA;                 int64_t channel_layout,&#xA;                 AVSampleFormat format)&#xA;{&#xA;    m_samplerate = samplerate;&#xA;    m_queue_limit = queue_limit;&#xA;    m_queue_dropfactor = queue_dropfactor;&#xA;    m_device_format = format;&#xA;    m_channel_layout = channel_layout;&#xA;&#xA;&#xA;    SDL_SetHint(SDL_HINT_THREAD_STACK_SIZE, "8388608");&#xA;&#xA;    if(codecName.empty())&#xA;        throw std::runtime_error("audio decoder: no codec specified.");&#xA;&#xA;    auto names = player::lookup_ffmpeg_decoders(codecName);&#xA;    if(names == nullptr)&#xA;        throw std::runtime_error("audio decoder: cannot find decoder names for {}"&#x2B;codecName);&#xA;&#xA;    audio_codec_id = player::lookup_codec_id(codecName);&#xA;    codec      = player::avcodec_find_decoder(names, AV_CODEC_ID_NONE);&#xA;    if(codec == nullptr)&#xA;        throw std::runtime_error("audio decoder: cannot find the decoder for {}"&#x2B;codecName);&#xA;&#xA;    adecoder = avcodec_alloc_context3(codec);&#xA;    if(adecoder == nullptr)&#xA;        throw std::runtime_error("audio decoder: cannot allocate context");&#xA;&#xA;    adecoder->channels   = channels;&#xA;    adecoder->sample_rate = samplerate;&#xA;    if(adecoder->channels == 1)&#xA;    {&#xA;        adecoder->channel_layout = AV_CH_LAYOUT_MONO;&#xA;    }&#xA;    else if(adecoder->channels == 2)&#xA;    {&#xA;        adecoder->channel_layout = AV_CH_LAYOUT_STEREO;&#xA;    }&#xA;    else&#xA;        throw std::runtime_error("audio decoder: unsupported number of channels ({})"&#x2B; adecoder->channels);&#xA;    &#xA;&#xA;    if(avcodec_open2(adecoder, codec, nullptr) != 0)&#xA;        throw std::runtime_error("audio decoder: cannot open decoder");&#xA;&#xA;    parser = av_parser_init(codec->id);&#xA;&#xA;    SDL_AudioSpec wanted, spec;&#xA;    wanted.freq     = samplerate;&#xA;    wanted.format   = AUDIO_S16SYS;&#xA;    wanted.channels = channels;&#xA;    wanted.silence  = 0;&#xA;    wanted.samples  = buffer_size;&#xA;    wanted.userdata = adecoder;&#xA;    wanted.callback = audio_callback;&#xA;    &#xA;&#xA;    m_id = SDL_OpenAudioDevice(nullptr, 0, &amp;wanted, &amp;spec, 0);&#xA;    if(m_id == 0)&#xA;        throw std::runtime_error(SDL_GetError());&#xA;&#xA;    SDL_PauseAudioDevice(m_id, 0);&#xA;}&#xA;&#xA;void close_Speaker()&#xA;{&#xA;    SDL_CloseAudioDevice(m_id);&#xA;    &#xA;    if(adecoder != nullptr)&#xA;        player::avcodec_close(adecoder);&#xA;&#xA;}&#xA;&#xA;void play(uint8_t* buffer, size_t bufsize, microseconds pts, microseconds dts)&#xA;{&#xA;    if(!buffer || !bufsize) {&#xA;        return;&#xA;    }&#xA;    &#xA;    AVPacket* avpkt;&#xA;    avpkt = av_packet_alloc();&#xA;    av_init_packet(avpkt);&#xA;    uint8_t bf[bufsize &#x2B; 64];&#xA;    memcpy(bf, buffer, bufsize);&#xA;&#xA;    av_parser_parse2(parser, adecoder, &amp;avpkt->data, &amp;avpkt->size,&#xA;                           bf, bufsize,&#xA;                           pts.count(), dts.count(), 0);&#xA;&#xA;    queue.put(av_packet_clone(avpkt));&#xA;    queue.drop(m_queue_limit, m_queue_dropfactor); &#xA;&#xA;}&#xA;&#xA;//&#xA;&#xA;void process(AVCodecContext* decoder, uint8_t* stream, int ssize)&#xA;{&#xA;    auto filled = fillBuffer(decoder, stream, ssize);&#xA;&#xA;    auto unfilled{(ssize - filled) / 4};&#xA;    auto dummy{sframes};&#xA;&#xA;    sframes = unfilled == 0 ? 0 : sframes &#x2B; unfilled;&#xA;    memset(stream &#x2B; filled, 0, unfilled * 4);&#xA;    &#xA;    if(sframes != dummy)&#xA;        queue.add_silence((int64_t)sframes * 1000000 / m_samplerate);&#xA;}&#xA;&#xA;int fillBuffer(AVCodecContext* decoder, uint8_t* stream, int ssize)&#xA;{&#xA;    int filled{};&#xA;    AVPacket avpkt;&#xA;    audio_buffer_init();&#xA;    while(filled &lt; ssize)&#xA;    {&#xA;        int dsize{}, delta{};&#xA;&#xA;        // buffer has enough data&#xA;        if(absize - abpos >= static_cast<unsigned int="int">(ssize - filled))&#xA;        {&#xA;            delta = ssize - filled;&#xA;            std::copy(buf &#x2B; abpos, buf &#x2B; abpos &#x2B; delta, stream);&#xA;            abpos &#x2B;= delta;&#xA;            filled &#x2B;= delta;&#xA;            return ssize;&#xA;        }&#xA;        else if(absize - abpos > 0)&#xA;        {&#xA;            delta = absize - abpos;&#xA;            std::copy(buf &#x2B; abpos, buf &#x2B; abpos &#x2B; delta, stream);&#xA;            stream &#x2B;= delta;&#xA;            filled &#x2B;= delta;&#xA;            abpos = absize = 0;&#xA;        }&#xA;        // move data to head, leave more ab buffers&#xA;        if(abpos != 0)&#xA;        {&#xA;            std::copy(buf &#x2B; abpos, buf &#x2B; abpos &#x2B; absize - abpos, buf);&#xA;            absize -= abpos;&#xA;            abpos = 0;&#xA;        }&#xA;        // decode more packets&#xA;        if(!queue.get(&amp;avpkt, false))&#xA;            break;&#xA;        if((dsize = decode(decoder, &amp;avpkt, buf &#x2B; absize, buffer_max_size - absize)) &lt; 0)&#xA;            break;&#xA;        absize &#x2B;= dsize;&#xA;    }&#xA;&#xA;    return filled;&#xA;}&#xA;&#xA;int decode(AVCodecContext* decoder, AVPacket* pkt, uint8_t* dstbuf, int dstlen)&#xA;{&#xA;    const uint8_t* srcplanes[SWR_CH_MAX];&#xA;    uint8_t* dstplanes[SWR_CH_MAX];&#xA;    int filled{};&#xA;&#xA;    AVFrame* aframe = av_frame_alloc();&#xA;&#xA;    auto saveptr = pkt->data;&#xA;&#xA;    while(pkt->size > 0)&#xA;    {&#xA;        int len{}, got_frame{};&#xA;        unsigned char* srcbuf{};&#xA;        int datalen{};&#xA;&#xA;        if((len = avcodec_decode_audio4(decoder, aframe, &amp;got_frame, pkt)) &lt; 0)&#xA;        {&#xA;            return -1;&#xA;        }&#xA;        if(got_frame == 0)&#xA;        {&#xA;            pkt->size -= len;&#xA;            pkt->data &#x2B;= len;&#xA;            continue;&#xA;        }&#xA;&#xA;        if(aframe->format == m_device_format)&#xA;        {&#xA;            datalen = av_samples_get_buffer_size(nullptr,&#xA;                                                 aframe->channels /*rtspconf->audio_channels*/,&#xA;                                                 aframe->nb_samples,&#xA;                                                 (AVSampleFormat)aframe->format,&#xA;                                                 1 /*no-alignment*/);&#xA;            srcbuf  = aframe->data[0];&#xA;        }&#xA;        else&#xA;        {&#xA;            // need conversion!&#xA;            if(swrctx == nullptr)&#xA;            {&#xA;                if((swrctx = swr_alloc_set_opts(nullptr,&#xA;                                                m_channel_layout,&#xA;                                                m_device_format,&#xA;                                                m_samplerate,&#xA;                                                aframe->channel_layout,&#xA;                                                (AVSampleFormat)aframe->format,&#xA;                                                aframe->sample_rate,&#xA;                                                0,&#xA;                                                nullptr)) == nullptr)&#xA;                {&#xA;                    return -1;&#xA;                }&#xA;                auto err = swr_init(swrctx);&#xA;                if(err &lt; 0)&#xA;                {&#xA;                    char msg[1024];&#xA;                    av_strerror(err, msg, 1024);&#xA;                    return -1;&#xA;                }&#xA;                max_decoder_size = av_samples_get_buffer_size(nullptr,&#xA;                                                              2, &#xA;                                                              m_samplerate,&#xA;                                                              m_device_format,&#xA;                                                              1 /*no-alignment*/);&#xA;                if((convbuf = (unsigned char*)::malloc(max_decoder_size)) == nullptr)&#xA;                {&#xA;                    return -1;&#xA;                }&#xA;            }&#xA;            datalen = av_samples_get_buffer_size(nullptr,&#xA;                                                 2,&#xA;                                                 aframe->nb_samples,&#xA;                                                 m_device_format,&#xA;                                                 1 /*no-alignment*/);&#xA;            if(datalen > max_decoder_size)&#xA;            {&#xA;                return -1;&#xA;            }&#xA;            srcplanes[0] = aframe->data[0];&#xA;            if(av_sample_fmt_is_planar((AVSampleFormat)aframe->format) != 0)&#xA;            {&#xA;                // planar&#xA;                int i;&#xA;                for(i = 1; i &lt; aframe->channels; i&#x2B;&#x2B;)&#xA;                {&#xA;                    srcplanes[i] = aframe->data[i];&#xA;                }&#xA;                srcplanes[i] = nullptr;&#xA;            }&#xA;            else&#xA;            {&#xA;                srcplanes[1] = nullptr;&#xA;            }&#xA;            dstplanes[0] = convbuf;&#xA;            dstplanes[1] = nullptr;&#xA;&#xA;            swr_convert(swrctx, dstplanes, aframe->nb_samples, srcplanes, aframe->nb_samples);&#xA;            srcbuf = convbuf;&#xA;        }&#xA;        if(datalen > dstlen)&#xA;        {&#xA;            datalen = dstlen;&#xA;        }&#xA;&#xA;        std::copy(srcbuf, srcbuf &#x2B; datalen, dstbuf);&#xA;        dstbuf &#x2B;= datalen;&#xA;        dstlen -= datalen;&#xA;        filled &#x2B;= datalen;&#xA;&#xA;        pkt->size -= len;&#xA;        pkt->data &#x2B;= len;&#xA;        av_frame_unref(aframe);&#xA;    }&#xA;    pkt->data = saveptr;&#xA;    if(pkt->data)&#xA;        av_packet_unref(pkt);&#xA;    if(aframe != nullptr)&#xA;        av_frame_free(&amp;aframe);&#xA;    &#xA;    return filled;&#xA;}&#xA;</unsigned></iostream>

    &#xA;

    In packet_queue.cpp :

    &#xA;

    #include "packet_queue.h"&#xA;&#xA;using player::PacketQueue;&#xA;using lock_guard  = std::lock_guard;&#xA;using unique_lock = std::unique_lock;&#xA;using std::chrono::milliseconds;&#xA;&#xA;PacketQueue::PacketQueue(uint32_t playback_queue_silence, bool playback_queue_debug) :&#xA;        m_playback_queue_debug(playback_queue_debug), m_playback_queue_silence(playback_queue_silence)&#xA;{&#xA;}&#xA;&#xA;void PacketQueue::clear()&#xA;{&#xA;    lock_guard lk{m_mtx};&#xA;    for(auto&amp; pkt : queue)&#xA;        av_packet_unref(pkt);&#xA;&#xA;    m_size = 0;&#xA;    queue.clear();&#xA;}&#xA;&#xA;void PacketQueue::add_silence(int64_t silence_pts)&#xA;{&#xA;    if(m_playback_queue_silence == 0)&#xA;    {&#xA;        return;&#xA;    }&#xA;&#xA;    lock_guard lk{m_mtx};&#xA;    silence_pts = filtered_packets > 0 ? silence_pts : last_pts &#x2B; silence_pts;&#xA;&#xA;    auto tv  = std::chrono::microseconds{last_pts};&#xA;    auto tv2 = std::chrono::microseconds{silence_pts};&#xA;}&#xA;&#xA;bool PacketQueue::put(AVPacket* pkt)&#xA;{&#xA;    if(pkt == nullptr)&#xA;    {&#xA;        return false;&#xA;    }&#xA;&#xA;    lock_guard lk{m_mtx};&#xA;    if((silence_pts - pkt->pts) > (m_playback_queue_silence * 1000))&#xA;    {&#xA;        auto tv = std::chrono::microseconds{pkt->pts};&#xA;        filtered_packets&#x2B;&#x2B;;&#xA;        if(m_playback_queue_debug)&#xA;        return true;&#xA;    }&#xA;&#xA;    queue.push_back(pkt);&#xA;    filtered_packets = 0;&#xA;    return true;&#xA;}&#xA;&#xA;bool PacketQueue::get(AVPacket* pkt, bool block, milliseconds timeout)&#xA;{&#xA;    unique_lock lk{m_mtx};&#xA;&#xA;    for(;;)&#xA;    {&#xA;        if(queue.size() > 0)&#xA;        {&#xA;            auto ptr = queue.front();&#xA;            queue.pop_front();&#xA;            m_size -= ptr->size;&#xA;            last_pts = ptr->pts;&#xA;            av_packet_move_ref(pkt, ptr);&#xA;            return true;&#xA;        }&#xA;        else if(!block)&#xA;        {&#xA;            return false;&#xA;        }&#xA;        else if(!m_cv.wait_for(lk, timeout, [&amp;] { return !queue.empty(); }))&#xA;        {&#xA;            return false;&#xA;        }&#xA;&#xA;    }&#xA;    return false;&#xA;}&#xA;&#xA;bool PacketQueue::drop(size_t limit, size_t dropfactor)&#xA;{&#xA;    int dropped, count = 0;&#xA;&#xA;    lock_guard lk{m_mtx};&#xA;&#xA;    // queue size exceeded?&#xA;    if(queue.size() &lt;= limit)&#xA;    {&#xA;        return false;&#xA;    }&#xA;&#xA;    // start dropping&#xA;    dropped = queue.size() / dropfactor;&#xA;    // keep at least one&#xA;    if(dropped == queue.size())&#xA;        dropped--;&#xA;&#xA;    AVPacket* pkt;&#xA;    while(dropped-- > 0 &amp;&amp; !queue.empty())&#xA;    {&#xA;        pkt = queue.front();&#xA;&#xA;        if(pkt->flags != AV_PKT_FLAG_KEY)&#xA;        {&#xA;            queue.pop_front();&#xA;            m_size -= pkt->size;&#xA;            av_packet_unref(pkt);&#xA;            &#x2B;&#x2B;count;&#xA;        }&#xA;    }&#xA;&#xA;    return true; // count;&#xA;}&#xA;&#xA;int PacketQueue::drop2(size_t limit, bool error)&#xA;{&#xA;    int count = 0;&#xA;&#xA;    // dropping enabled?&#xA;    if(limit &lt;= 0 &amp;&amp; !error)&#xA;        return 0;&#xA;&#xA;    lock_guard lk{m_mtx};&#xA;    // queue size exceeded?&#xA;    if(queue.size() &lt;= limit &amp;&amp; !error)&#xA;        return false;&#xA;&#xA;    for(auto i = queue.begin(); i != queue.end();)&#xA;    {&#xA;        AVPacket* pkt = *i;&#xA;        if(pkt->flags != AV_PKT_FLAG_KEY)&#xA;        {&#xA;            m_size -= pkt->size;&#xA;            av_packet_unref(pkt);&#xA;            i = queue.erase(i);&#xA;            count&#x2B;&#x2B;;&#xA;        }&#xA;        else&#xA;            &#x2B;&#x2B;i;&#xA;    }&#xA;&#xA;    return count;&#xA;}&#xA;

    &#xA;

    1403 line of celt/bands.c :&#xA;screenshot

    &#xA;

    Versions of libraries that I tried on Debian 9 :&#xA;libavcodec.so.57.64.101 and libopus.so.0.5.3

    &#xA;

    also I built manually libavcodec.so.57.107.100 and libopus.so.0.8.0 and tried to use them - the same error appears.

    &#xA;

    As I already mentioned, everything works fine on Windows 10 and Ubuntu 18.04. So I have no clue what could be the reason of the issue. Any help is appreciated.

    &#xA;

  • Use Named Pipe (C++) to send images to FFMPEG

    28 août 2015, par user1829136

    I have the following code in C++ :

    #include <iostream>
    #include
    #include <iostream>     // std::cout
    #include <fstream>      // std::ifstream
    #include <vector>
    #include

    using namespace std;

    int main(int argc, const char **argv)
    {
       wcout &lt;&lt; "Creating an instance of a named pipe..." &lt;&lt; endl;

       // Create a pipe to send data
       HANDLE pipe = CreateNamedPipe(
           L"\\\\.\\pipe\\my_pipe", // name of the pipe
           PIPE_ACCESS_OUTBOUND, // 1-way pipe -- send only
           PIPE_TYPE_BYTE, // send data as a byte stream
           1, // only allow 1 instance of this pipe
           0, // no outbound buffer
           0, // no inbound buffer
           0, // use default wait time
           NULL // use default security attributes
       );

       if (pipe == NULL || pipe == INVALID_HANDLE_VALUE) {
           wcout &lt;&lt; "Failed to create outbound pipe instance.";
           // look up error code here using GetLastError()
           system("pause");
           return 1;
       }

       wcout &lt;&lt; "Waiting for a client to connect to the pipe..." &lt;&lt; endl;

       // This call blocks until a client process connects to the pipe
       BOOL result = ConnectNamedPipe(pipe, NULL);
       if (!result) {
           wcout &lt;&lt; "Failed to make connection on named pipe." &lt;&lt; endl;
           // look up error code here using GetLastError()
           CloseHandle(pipe); // close the pipe
           system("pause");
           return 1;
       }

       wcout &lt;&lt; "Sending data to pipe..." &lt;&lt; endl;

       //opening file
       ifstream infile;
       infile.open("E:/xmen.jpg",std::ios::binary);
       ofstream out("E:/lelel.jpg",std::ios::binary);

       infile.seekg(0,std::ios::end);
       size_t file_size_in_byte = infile.tellg();
       vector<char> file_vec;

       file_vec.resize(file_size_in_byte);

       infile.seekg(0,std::ios::beg);
       infile.read(&amp;file_vec[0],file_size_in_byte);

       out.write(&amp;file_vec[0],file_vec.size());

       wcout&lt;/ This call blocks until a client process reads all the data
       DWORD numBytesWritten = 0;
       result = WriteFile(
           pipe, // handle to our outbound pipe
           &amp;file_vec[0], // data to send
           61026, // length of data to send (bytes)
           &amp;numBytesWritten, // will store actual amount of data sent
           NULL // not using overlapped IO
       );


       if (result) {
           wcout &lt;&lt; "Number of bytes sent: " &lt;&lt; numBytesWritten &lt;&lt; endl;
       } else {
           wcout &lt;&lt; "Failed to send data." &lt;&lt; endl;
           // look up error code here using GetLastError()
       }

       // Close the pipe (automatically disconnects client too)
       CloseHandle(pipe);

       wcout &lt;&lt; "Done." &lt;&lt; endl;

       system("pause");
       return 0;
    }
    </char></vector></fstream></iostream></iostream>

    Which I use to create a named pipe \.\pipe\my_pipe, to which FFMPEG connects to, using the following command :

    64-static\bin\Video>ffmpeg.exe -loop 1 -s 4cif -f image2 -y -i \\.\pipe\\my_pipe

    -r 25 -vframes 250 -vcodec rawvideo -an eaeew.mov

    Output :

    ffmpeg version N-54233-g86190af Copyright (c) 2000-2013 the FFmpeg developers
     built on Jun 27 2013 16:49:12 with gcc 4.7.3 (GCC)
     configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libcaca --enable-libfreetype --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libxavs --enable-libxvid --enable-zlib  libavutil      52. 37.101 / 52. 37.101
     libavcodec     55. 17.100 / 55. 17.100
     libavformat    55. 10.100 / 55. 10.100
     libavdevice    55.  2.100 / 55.  2.100
     libavfilter     3. 77.101 /  3. 77.101
     libswscale      2.  3.100 /  2.  3.100
     libswresample   0. 17.102 /  0. 17.102
     libpostproc    52.  3.100 / 52.  3.100
    [image2 @ 0000000003ee04a0] Could find no file with with path '\\.\pipe\\my_pipe
    ' and index in the range 0-4
    \\.\pipe\\my_pipe: No such file or directory

    I can see on my console that my C++ app received a connection, but I get the error above in FFMPEG. Can someone please advise ?

    EDIT 1
    Using the command below

    ffmpeg.exe -s 4cif -i \\.\pipe\my_pipe -r 25 -vframes 250 -vcodec rawvideo -an tess.mov

    I get the following output

    ffmpeg version N-54233-g86190af Copyright (c) 2000-2013 the FFmpeg developers
     built on Jun 27 2013 16:49:12 with gcc 4.7.3 (GCC)
     configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libcaca --enable-libfreetype --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libxavs --enable-libxvid --enable-zlib
     libavutil      52. 37.101 / 52. 37.101
     libavcodec     55. 17.100 / 55. 17.100
     libavformat    55. 10.100 / 55. 10.100
     libavdevice    55.  2.100 / 55.  2.100
     libavfilter     3. 77.101 /  3. 77.101
     libswscale      2.  3.100 /  2.  3.100
     libswresample   0. 17.102 /  0. 17.102
     libpostproc    52.  3.100 / 52.  3.100
    \\.\pipe\my_pipe: Invalid data found when processing input

    So, now it seems it was able to connect to the pipe but is not able to process the input.

  • Uploading video to Twitter sometimes doesn't work

    22 juillet 2021, par K-s S-k

    I have a very difficult situation. I've already spent 2 days and couldn't find a solution. Project on Laravel. I want to upload videos to Twitter using the Twitter API endpoints. But sometimes I am getting this error :

    &#xA;

    &#xA;

    file is currently unsupported

    &#xA;

    &#xA;

    I did everything as recommended in the official documentation Video specifications and recommendations. I get an error when I set an audio codec is aac in my video file, despite the fact that it is recommended in the official documentation, but when I set the audio codec to mp3, the video is uploaded, but the sound quality is very poor, and sometimes there is no sound at all. Please forgive me if this is awkward to read, but I want to provide all of my code. Because I don't know how to solve this anymore and I think it might help.

    &#xA;

    &lt;?php&#xA;&#xA;namespace App\Jobs;&#xA;&#xA;use App\Models\PublishedContent;&#xA;use Atymic\Twitter\Facades\Twitter;&#xA;use GuzzleHttp\Client as GuzzleClient;&#xA;use GuzzleHttp\Exception\GuzzleException;&#xA;use Illuminate\Bus\Queueable;&#xA;use Illuminate\Support\Facades\Log;&#xA;use Illuminate\Support\Facades\File;&#xA;use Illuminate\Queue\SerializesModels;&#xA;use Illuminate\Queue\InteractsWithQueue;&#xA;use Illuminate\Contracts\Queue\ShouldQueue;&#xA;use Illuminate\Foundation\Bus\Dispatchable;&#xA;use Illuminate\Support\Str;&#xA;&#xA;&#xA;class PublishToTwitter implements ShouldQueue&#xA;{&#xA;    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;&#xA;&#xA;    /**&#xA;     * @var&#xA;     */&#xA;    protected $publishingData;&#xA;&#xA;    /**&#xA;     * Create a new job instance.&#xA;     *&#xA;     * @param $publishingData&#xA;     */&#xA;    public function __construct($publishingData)&#xA;    {&#xA;        $this->publishingData = $publishingData;&#xA;    }&#xA;&#xA;    /**&#xA;     * Execute the job.&#xA;     *&#xA;     * @return void&#xA;     */&#xA;    public function handle()&#xA;    {&#xA;        $publishingData = $this->publishingData;&#xA;&#xA;        if (is_array($publishingData)) {&#xA;            $publishingResult = $this->publishing(...array_values($publishingData));&#xA;            sendNotification($publishingResult[&#x27;message&#x27;], $publishingResult[&#x27;status&#x27;], &#x27;Twitter&#x27;, $publishingResult[&#x27;link&#x27;], $publishingData[&#x27;post_name&#x27;], $publishingData[&#x27;user&#x27;]);&#xA;        } else {&#xA;            $scheduledData = processingScheduledPost($publishingData);&#xA;            $postName = $scheduledData[&#x27;scheduleData&#x27;][&#x27;post_name&#x27;];&#xA;            $postContent = $scheduledData[&#x27;scheduleData&#x27;][&#x27;post_content&#x27;];&#xA;            $userToken = json_decode($publishingData->user_token,true);&#xA;            $requestToken = [&#xA;                &#x27;token&#x27;  => $userToken[&#x27;oauth_token&#x27;],&#xA;                &#x27;secret&#x27; => $userToken[&#x27;oauth_token_secret&#x27;],&#xA;            ];&#xA;            $publishingResult = $this->publishing($scheduledData[&#x27;file&#x27;], $postName, $postContent, $requestToken);&#xA;            $publishingResult[&#x27;status&#x27;] &amp;&amp; PublishedContent::add($scheduledData[&#x27;craft&#x27;], $scheduledData[&#x27;file&#x27;], "twitter_share");&#xA;            sendResultToUser($publishingData, $scheduledData[&#x27;user&#x27;], $publishingResult[&#x27;message&#x27;], $postName, $publishingResult[&#x27;link&#x27;], $publishingResult[&#x27;publishing_status&#x27;], $scheduledData[&#x27;social_media&#x27;]);&#xA;            sendNotification($publishingResult[&#x27;message&#x27;], $publishingResult[&#x27;status&#x27;], &#x27;Twitter&#x27;, $publishingResult[&#x27;link&#x27;], $postName, $scheduledData[&#x27;user&#x27;]);&#xA;        }&#xA;    }&#xA;&#xA;    /**&#xA;     * @param $file&#xA;     * @param $postName&#xA;     * @param $postContent&#xA;     * @param $requestToken&#xA;     * @return array&#xA;     */&#xA;    private function publishing($file, $postName, $postContent, $requestToken): array&#xA;    {&#xA;        $result = [&#xA;            &#x27;status&#x27; => false,&#xA;            &#x27;link&#x27; => null,&#xA;            &#x27;message&#x27; => &#x27;Your content can\&#x27;t successfully published on Twitter. This file is not supported for publishing.&#x27;,&#xA;            &#x27;publishing_status&#x27; => &#x27;error&#x27;&#xA;        ];&#xA;&#xA;        if ((($file->refe_type !== &#x27;text&#x27;) || $file->refe_file_path) &amp;&amp; !checkIfFileExist($file->refe_file_path)) {&#xA;            $result[&#x27;message&#x27;] = &#x27;Missing or invalid file.&#x27;;&#xA;            return $result;&#xA;        }&#xA;&#xA;        $filePath = $file->refe_file_path;&#xA;        $fileSize = $file->content_length;&#xA;        $tempFileName = &#x27;temp-&#x27; . $file->refe_file_name;&#xA;        $ext = $file->file_type;&#xA;        $mediaCategory = &#x27;tweet_&#x27; . $file->refe_type;&#xA;        $mediaType = $file->refe_type . &#x27;/&#x27; . $ext;&#xA;        $remoteFile = file_get_contents($filePath);&#xA;        $tempFolder = public_path(&#x27;/storage/uploads/temp&#x27;);&#xA;&#xA;        if (!file_exists($tempFolder)) {&#xA;            mkdir($tempFolder, 0777, true);&#xA;        }&#xA;&#xA;        $tempFile = public_path(&#x27;/storage/uploads/temp/&#x27; . $tempFileName);&#xA;        File::put($tempFile, $remoteFile);&#xA;        $convertedFileName = &#x27;converted-&#x27; . $file->refe_file_name;&#xA;        $convertedFile = public_path(&#x27;/storage/uploads/temp/&#x27; . $convertedFileName);&#xA;        $command = &#x27;ffmpeg -y -i &#x27;.$tempFile.&#x27; -b:v 5000k -b:a 380k -c:a aac -profile:a aac_low -threads 1 &#x27;.$convertedFile.&#x27;&#x27;;&#xA;        exec($command);&#xA;        @File::delete($tempFile);&#xA;&#xA;        try {&#xA;            $twitter = Twitter::usingCredentials($requestToken[&#x27;token&#x27;], $requestToken[&#x27;secret&#x27;]);&#xA;            if ($file->refe_type === &#x27;text&#x27;) {&#xA;                $twitter->postTweet([&#xA;                    &#x27;status&#x27; => urldecode($postContent),&#xA;                    &#x27;format&#x27; => &#x27;json&#x27;,&#xA;                ]);&#xA;&#xA;                $result[&#x27;link&#x27;] = &#x27;https://twitter.com/home&#x27;;&#xA;                $result[&#x27;status&#x27;] = true;&#xA;                $result[&#x27;message&#x27;] = &#x27;Your content successfully published on Twitter. You can visit to Twitter and check it.&#x27;;&#xA;                $result[&#x27;publishing_status&#x27;] = &#x27;done&#x27;;&#xA;            } else if ($file->refe_type === &#x27;video&#x27; || $file->refe_type === &#x27;image&#x27;) {&#xA;                if ($file->refe_type === &#x27;video&#x27;) {&#xA;                    $duration = getVideoDuration($file->refe_file_path);&#xA;&#xA;                    if ($duration > config(&#x27;constant.sharing_configs.max_video_duration.twitter&#x27;)) {&#xA;                        throw new \Exception(&#x27;The duration of the video file must not exceed 140 seconds.&#x27;);&#xA;                    }&#xA;                }&#xA;&#xA;                $isFileTypeSupported = checkPublishedFileType(&#x27;twitter&#x27;, $file->refe_type, strtolower($ext));&#xA;                $isFileSizeSupported = checkPublishedFileSize(&#x27;twitter&#x27;, $file->refe_type, $fileSize, strtolower($ext));&#xA;&#xA;                if (!$isFileTypeSupported) {&#xA;                    throw new \Exception(&#x27;Your content can\&#x27;t successfully published on Twitter. This file type is not supported for publishing.&#x27;);&#xA;                }&#xA;&#xA;                if (!$isFileSizeSupported) {&#xA;                    throw new \Exception(&#x27;Your content can\&#x27;t successfully published on Twitter. The file size is exceeded.&#x27;);&#xA;                }&#xA;&#xA;                if ($file->refe_type === &#x27;video&#x27;) $fileSize = filesize($convertedFile);&#xA;&#xA;                if (strtolower($ext) === &#x27;gif&#x27;) {&#xA;                    $initMedia = $twitter->uploadMedia([&#xA;                        &#x27;command&#x27; => &#x27;INIT&#x27;,&#xA;                        &#x27;total_bytes&#x27; => (int)$fileSize&#xA;                    ]);&#xA;                } else {&#xA;                    $initMedia = $twitter->uploadMedia([&#xA;                        &#x27;command&#x27; => &#x27;INIT&#x27;,&#xA;                        &#x27;media_type&#x27; => $mediaType,&#xA;                        &#x27;media_category&#x27; => $mediaCategory,&#xA;                        &#x27;total_bytes&#x27; => (int)$fileSize&#xA;                    ]);&#xA;                }&#xA;&#xA;                $mediaId = (int)$initMedia->media_id_string;&#xA;&#xA;                $fp = fopen($convertedFile, &#x27;r&#x27;);&#xA;                $segmentId = 0;&#xA;&#xA;                while (!feof($fp)) {&#xA;                    $chunk = fread($fp, 1048576);&#xA;&#xA;                    $twitter->uploadMedia([&#xA;                        &#x27;media_data&#x27; => base64_encode($chunk),&#xA;                        &#x27;command&#x27; => &#x27;APPEND&#x27;,&#xA;                        &#x27;segment_index&#x27; => $segmentId,&#xA;                        &#x27;media_id&#x27; => $mediaId&#xA;                    ]);&#xA;&#xA;                    $segmentId&#x2B;&#x2B;;&#xA;                }&#xA;&#xA;                fclose($fp);&#xA;&#xA;                $twitter->uploadMedia([&#xA;                    &#x27;command&#x27; => &#x27;FINALIZE&#x27;,&#xA;                    &#x27;media_id&#x27; => $mediaId&#xA;                ]);&#xA;&#xA;                if ($file->refe_type === &#x27;video&#x27;) {&#xA;                    $waits = 0;&#xA;&#xA;                    while ($waits &lt;= 4) {&#xA;                        // Authorizing header for Twitter API&#xA;                        $oauth = [&#xA;                            &#x27;command&#x27; => &#x27;STATUS&#x27;,&#xA;                            &#x27;media_id&#x27; => $mediaId,&#xA;                            &#x27;oauth_consumer_key&#x27; => config(&#x27;twitter.consumer_key&#x27;),&#xA;                            &#x27;oauth_nonce&#x27; => Str::random(42),&#xA;                            &#x27;oauth_signature_method&#x27; => &#x27;HMAC-SHA1&#x27;,&#xA;                            &#x27;oauth_timestamp&#x27; => time(),&#xA;                            &#x27;oauth_token&#x27; => $requestToken[&#x27;token&#x27;],&#xA;                            &#x27;oauth_version&#x27; => &#x27;1.0&#x27;&#xA;                        ];&#xA;&#xA;                        // Generate an OAuth 1.0a HMAC-SHA1 signature for an HTTP request&#xA;                        $baseInfo = $this->buildBaseString(&#x27;https://upload.twitter.com/1.1/media/upload.json&#x27;, &#x27;GET&#x27;, $oauth);&#xA;                        // Getting a signing key&#xA;                        $compositeKey = rawurlencode(config(&#x27;twitter.consumer_secret&#x27;)) . &#x27;&amp;&#x27; . rawurlencode($requestToken[&#x27;secret&#x27;]);&#xA;                        // Calculating the signature&#xA;                        $oauthSignature = base64_encode(hash_hmac(&#x27;sha1&#x27;, $baseInfo, $compositeKey, true));&#xA;                        $oauth[&#x27;oauth_signature&#x27;] = $oauthSignature;&#xA;                        $headers[&#x27;Authorization&#x27;] = $this->buildAuthorizationHeader($oauth);&#xA;&#xA;                        try {&#xA;                            $guzzle = new GuzzleClient([&#xA;                                &#x27;headers&#x27; => $headers&#xA;                            ]);&#xA;                            $response = $guzzle->request( &#x27;GET&#x27;, &#x27;https://upload.twitter.com/1.1/media/upload.json?command=STATUS&amp;media_id=&#x27; . $mediaId);&#xA;                            $uploadStatus = json_decode($response->getBody()->getContents());&#xA;                        } catch (\Exception | GuzzleException $e) {&#xA;                            dd($e->getMessage(), $e->getLine(), $e->getFile());&#xA;                        }&#xA;&#xA;                        if (isset($uploadStatus->processing_info->state)) {&#xA;                            switch ($uploadStatus->processing_info->state) {&#xA;                                case &#x27;succeeded&#x27;:&#xA;                                    $waits = 5; // break out of the while loop&#xA;                                    break;&#xA;                                case &#x27;failed&#x27;:&#xA;                                    File::delete($tempFile);&#xA;                                    Log::error(&#x27;File processing failed: &#x27; . $uploadStatus->processing_info->error->message);&#xA;                                    throw new \Exception(&#x27;File processing failed: &#x27; . $uploadStatus->processing_info->error->message);&#xA;                                default:&#xA;                                    sleep($uploadStatus->processing_info->check_after_secs);&#xA;                                    $waits&#x2B;&#x2B;;&#xA;                            }&#xA;                        } else {&#xA;                            throw new \Exception(&#x27;There was an unknown error uploading your file&#x27;);&#xA;                        }&#xA;                    }&#xA;                }&#xA;&#xA;                $twitter->postTweet([&#x27;status&#x27; => urldecode($postContent), &#x27;media_ids&#x27; => $initMedia->media_id_string]);&#xA;                @File::delete($convertedFile);&#xA;                $result[&#x27;link&#x27;] = &#x27;https://twitter.com/home&#x27;;&#xA;                $result[&#x27;status&#x27;] = true;&#xA;                $result[&#x27;message&#x27;] = &#x27;Your content successfully published on Twitter. You can visit to Twitter and check it.&#x27;;&#xA;                $result[&#x27;publishing_status&#x27;] = &#x27;done&#x27;;&#xA;            }&#xA;        } catch (\Exception $e) {&#xA;            dd($e->getMessage());&#xA;            $result[&#x27;message&#x27;] = $e->getMessage();&#xA;            return $result;&#xA;        }&#xA;&#xA;        return $result;&#xA;    }&#xA;&#xA;    /**&#xA;     * @param $baseURI&#xA;     * @param $method&#xA;     * @param $params&#xA;     * @return string&#xA;     *&#xA;     * Creating the signature base string&#xA;     */&#xA;    protected function buildBaseString($baseURI, $method, $params): string&#xA;    {&#xA;        $r = array();&#xA;        ksort($params);&#xA;        foreach($params as $key=>$value){&#xA;            $r[] = "$key=" . rawurlencode($value);&#xA;        }&#xA;        return $method . "&amp;" . rawurlencode($baseURI) . &#x27;&amp;&#x27; . rawurlencode(implode(&#x27;&amp;&#x27;, $r));&#xA;    }&#xA;&#xA;    /**&#xA;     * @param $oauth&#xA;     * @return string&#xA;     *&#xA;     * Collecting parameters&#xA;     */&#xA;    protected function buildAuthorizationHeader($oauth): string&#xA;    {&#xA;        $r = &#x27;OAuth &#x27;;&#xA;        $values = array();&#xA;        foreach($oauth as $key=>$value)&#xA;            $values[] = "$key=\"" . rawurlencode($value) . "\"";&#xA;        $r .= implode(&#x27;, &#x27;, $values);&#xA;        return $r;&#xA;    }&#xA;}&#xA;&#xA;

    &#xA;

    I would be very grateful if someone would help me.

    &#xA;