Как правильно использовать ffmpeg c++

124
23 ноября 2019, 05:30

Есть небольшая задача для обработки аудио информации. Не совсем понимаю как правильно воспользоваться функцией encode. Необходимо зашифровать аудио данные и сохранить информацию. Сразу хочу сказать что хотелось воспользоваться готовым шаблоном аудио данных что бы так называемый заголовок формировался автоматический в зависимости от кодека. Написал следующий класс:

class AudioFileWriter : public soundiocpp::InStream::IReader
{
public:
    explicit AudioFileWriter(const std::string filename);
    ~AudioFileWriter() override;
    void encode(enum AVCodecID id, AVSampleFormat f);
private:
    bool check_fmt();
    int sample_rate_supported();
    int channel_layout();
    static void register_if_need();
    AVCodec *codec;
    AVCodecContext *_format;
    std::string namef;
    AVFormatContext *s;
    AVOutputFormat *outFmt;
    AVFrame *frame;
    FILE *f;
    AVPacket pkt;
    static constexpr char* output_formats[5] = { NULL, "mp3", "wav", "wma", "ogg" };
public:
    int availableReadFrames(int min, int max) override;
    void readSample(int channel, char *ptr, int size) override;
    void overflow() override;
    void readError(int err) override;
};

Приводить функции формирования формата и всего не буду там ошибок нет точно. Существует функция:

  void AudioFileWriter::encode( enum AVCodecID id,AVSampleFormat f )
{
    codec = avcodec_find_encoder(id);
    if (!codec)
        throw std::invalid_argument("This encoder is not available for this system!");
    _format = avcodec_alloc_context3(codec);
    if (!_format)
          throw std::invalid_argument("cannot allocate memory for AVFormatContext");
    _format->bit_rate = 128000;
    _format->sample_rate = f;
    if (!check_fmt())
        throw std::invalid_argument("encoder does not support sample format");
    _format->sample_rate = sample_rate_supported();
    _format->channel_layout = channel_layout();
    _format->channels = av_get_channel_layout_nb_channels(_format->channel_layout);
    if (avcodec_open2( _format,codec,NULL ) < 0)
        throw std::invalid_argument("cannot open codec");\
    s = avformat_alloc_context();

    if ( !s )
        throw std::invalid_argument("cannot allocate media context");
    outFmt = av_guess_format("mp3",NULL,NULL);
    avformat_alloc_output_context2(&s,outFmt,output_formats[1],NULL);
    frame = av_frame_alloc();
    if (!frame)
         throw std::invalid_argument("Could not allocate audio frame");
    frame->nb_samples = _format->frame_size;
    frame->format = _format->sample_fmt;
    frame->channel_layout = _format->channel_layout;
}

Далее у меня есть обрабочик который вызывается когда у меня появляется информация с устройства записи или воспроизведения.

void AudioFileWriter::readSample(int channel, char *ptr, int size)
{
    int out;
    av_init_packet(&pkt);
    out = avcodec_encode_audio2(_format,&pkt,frame,(int*)ptr);
} 

Вот и далее я не совсем понимаю , на сколько я понял из документации и примеров out в моей последней функции кодируется и его я уже записывать в файл должен но как обьединить его с уже готовым контейнером который сформирует данные что бы мои данные были не в формате рафф? За любую помощь буду крайне признателен.

READ ALSO
Как получить доступ к полям класса, который в свою очередь является полем шаблонного класса?

Как получить доступ к полям класса, который в свою очередь является полем шаблонного класса?

В данном случае параметром шаблона функции является класс матрица, в arr находится сама матрицаНеобходимо инициализировать arr (сделать обычную...

112
Русский язык в GUI приложении Qt

Русский язык в GUI приложении Qt

Пишу GUI приложение на QtХочу установить title окна "Текстовый редактор", но отображаются "Крокозябры"

136
Как добавить виджет в компоновку?

Как добавить виджет в компоновку?

Помогите, пожалуйста, добавить текстовое поле внутрь окна wПочему-то выходит создать два отдельных окна

105
Как написать код, работающий на GCC и VC++?

Как написать код, работающий на GCC и VC++?

Известно, что оба компиля не дружат между собой, и один код, работающий с одним из них, не будет компилиться на другом, если в нём присутствуют...

131