I am trying to record audio from speaker.
I am using below code to create audio file.
The audio file is created but there is no audio data in file.
Or some time only 2-3 sec of audio  data is recorded.

I have gone through the ffmpeg examples.

can some one help me by seeing the below code.
Thanks.


ref struct WriterData
{
        public:
                Ffmpeg::AVFormatContext*                FormatContext;
                
                Ffmpeg::AVStream*                               AudioStream;
                Ffmpeg::AVFrame*                                AudioFrame;
                Ffmpeg::AVCodec                         *Audio_Codec;

                int AudioBitRate;
                int SampleRate;
                int Channels;
                
                int AudioReceived;
                int AudioWritten;

                Ffmpeg::int64_t next_pts;
                int samples_count;

                Ffmpeg::AVFrame *tmp_frame;

                float t, tincr, tincr2;
                struct Ffmpeg::SwsContext *sws_ctx;
                struct Ffmpeg::SwrContext *swr_ctx;

                double PreviousAudioDts;

                AudioWriterData()
                {
                        FormatContext = NULL;
                                
                        AudioStream = NULL;

                        Audio_Codec = NULL;

                        AudioFrame = NULL;
                        
                        AudioReceived = 0;
                        AudioWritten = 0;
                }
};

void Encoder::Open(String^ fileName, AudioCodec audioCodec, int
audioBitrate, int sampleRate, int channels)
{
        CheckIfDisposed();

        Close();

        data = gcnew WriterData();
        bool success = false;
                
        if (((int)audioCodec < -1) || ((int)audioCodec >= AUDIO_CODECS_COUNT))
                throw gcnew ArgumentException("Invalid audio codec is 
specified.");

        m_acodec = audioCodec;
        m_audioBitrate = audioBitrate;
        m_sampleRate = sampleRate;
        m_channels = channels;
                
        data->AudioBitRate = audioBitrate;
        data->SampleRate = sampleRate;
        data->Channels = channels;

        char* nativeFileName =
(char*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(fileName).ToPointer();

        try
        {
                Ffmpeg::AVOutputFormat* outputFormat = 
Ffmpeg::av_guess_format(NULL,
nativeFileName, NULL);

                if (!outputFormat)
                {
                        outputFormat = Ffmpeg::av_guess_format("mp3", NULL, 
NULL);

                        if (!outputFormat)
                                throw gcnew Exception("Cannot find suitable 
output format.");
                }

                data->FormatContext = Ffmpeg::avformat_alloc_context();

                if (!data->FormatContext)
                        throw gcnew Exception("Cannot allocate format 
context.");

                data->FormatContext->oformat = outputFormat;
                strcpy_s(data->FormatContext->filename, nativeFileName);

                Ffmpeg::AVCodecID codecId = (audioCodec == AudioCodec::Default) 
?
outputFormat->audio_codec : (Ffmpeg::AVCodecID)
audio_codecs[(int)audioCodec];

                data->FormatContext->oformat->audio_codec = codecId;

                add_audio_stream(data, codecId);
                                
                open_audio(data);

                Ffmpeg::av_dump_format(data->FormatContext, 0, nativeFileName, 
1);

                if (!(outputFormat->flags & AVFMT_NOFILE))
                {
                        if (Ffmpeg::avio_open(&data->FormatContext->pb, 
nativeFileName,
AVIO_FLAG_WRITE) < 0)
                                throw gcnew System::IO::IOException("Cannot 
open the video file.");
                }

                Ffmpeg::avformat_write_header(data->FormatContext, NULL);

                success = true;
        }
        finally
        {
                nativeFileName = NULL;
                delete[] nativeFileName;

                if (!success)
                        Close();
        }
}

void add_audio_stream(WriterData^ data, enum Ffmpeg::AVCodecID codecId)
{
        data->AudioStream = Ffmpeg::avformat_new_stream(data->FormatContext,
data->FormatContext->audio_codec);

        if (!data->AudioStream)
                throw gcnew Exception("Could not alloc audio stream");

        Ffmpeg::AVCodecContext *codecContext = data->AudioStream->codec;

        codecContext->codec_id = codecId;
        codecContext->codec_type = Ffmpeg::AVMEDIA_TYPE_AUDIO;
        codecContext->sample_fmt = Ffmpeg::AV_SAMPLE_FMT_S16;
        codecContext->channels = data->Channels;
        codecContext->delay = 0;
        codecContext->bit_rate = data->AudioBitRate;

        if (codecContext->bit_rate == 0)
                codecContext->bit_rate = data->SampleRate * data->Channels * 16;

        codecContext->bit_rate = codecContext->bit_rate;
        codecContext->bit_rate_tolerance = codecContext->bit_rate;
        codecContext->rc_min_rate = 0;
        codecContext->rc_max_rate = 0;
        codecContext->frame_size = 0;
        codecContext->channel_layout = (codecContext->channels == 2 ?
AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO);

        codecContext->sample_rate = data->SampleRate;

        codecContext->time_base.den = data->SampleRate;
        codecContext->time_base.num = 1;

        //data->AudioStream->time_base.den = codecContext->time_base.den;
        //data->AudioStream->time_base.num = codecContext->time_base.num;
                                                
        if (data->FormatContext->oformat->flags & AVFMT_GLOBALHEADER)
                codecContext->flags |= CODEC_FLAG_GLOBAL_HEADER;
}

void open_audio(WriterData^ data)
{
        Ffmpeg::AVCodecContext* codecContext = data->AudioStream->codec;
        Ffmpeg::AVCodec* codec = avcodec_find_encoder(codecContext->codec_id);

        if (!codec)
                throw gcnew Exception("Cannot find audio codec.");

        codecContext->codec_id = codec->id;
        codecContext->codec_type = Ffmpeg::AVMEDIA_TYPE_AUDIO;
        codecContext->sample_fmt = codec->sample_fmts[0];
        codecContext->sample_rate = data->SampleRate;
        codecContext->channel_layout = AV_CH_LAYOUT_STEREO;
        codecContext->channels =
Ffmpeg::av_get_channel_layout_nb_channels(codecContext->channel_layout);
        codecContext->bit_rate = data->AudioBitRate;

        int ret = Ffmpeg::avcodec_open2(codecContext, codec, NULL);
        if (ret < 0)
                throw gcnew Exception("Cannot open audio codec.");
}


void Encoder::WriteAudioChunk(IntPtr chunk, int lenght, TimeSpan timestamp)
{
        CheckIfDisposed();

        if (data == nullptr)
                throw gcnew System::IO::IOException("A video file was not 
opened yet.");

        int bufferSize = lenght;
                        
        data->AudioFrame = Ffmpeg::av_frame_alloc();

        Ffmpeg::av_frame_unref(data->AudioFrame);
        data->AudioFrame->pts = AV_NOPTS_VALUE;
        data->AudioFrame->format = data->AudioStream->codec->sample_fmt;

        int bytePerSample =
Ffmpeg::av_get_bytes_per_sample(data->AudioStream->codec->sample_fmt);
        int dataSize = data->Channels * bytePerSample;                  
        data->AudioStream->codec->frame_size = data->Channels *
data->SampleRate * bytePerSample;
        data->AudioFrame->nb_samples = data->AudioStream->codec->frame_size;

        Ffmpeg::uint8_t *buf =
reinterpret_cast<Ffmpeg::uint8_t*>(static_cast<void*>(chunk));

        int ret = Ffmpeg::avcodec_fill_audio_frame(data->AudioFrame,
data->Channels, data->AudioStream->codec->sample_fmt, buf, bufferSize,
1);

        if (!ret)
                throw gcnew System::IO::IOException("A video file was not 
opened yet.");
                        
        data->AudioReceived++;
        
        write_audio_chunk(data, buf, ret,timestamp.TotalMilliseconds);
}

void write_audio_chunk(WriterData^ data, Ffmpeg::uint8_t *ut, int
size,double timeStamp)
{
        Ffmpeg::AVCodecContext* codecContext = data->AudioStream->codec;
        int out_size, ret = 0;

        Ffmpeg::AVPacket packet;

        int64_t dts = timeStamp;
        dts = dts * data->FrameRate;

        if (data->PreviousAudioDts < 0)
                data->PreviousAudioDts = dts;

        int got_packet;
        Ffmpeg::av_init_packet(&packet);
        packet.data = ut;
        packet.size = size;

        out_size = Ffmpeg::avcodec_send_frame(codecContext, data->AudioFrame);
        got_packet = Ffmpeg::avcodec_receive_packet(codecContext, &packet);

        

        if (got_packet)
        {
                if (codecContext->coded_frame->pts != AV_NOPTS_VALUE)
                {
                        packet.pts = Ffmpeg::av_rescale_q(packet.pts,
codecContext->time_base, data->AudioStream->time_base);
                        packet.dts = Ffmpeg::av_rescale_q(packet.dts,
codecContext->time_base, data->AudioStream->time_base);
                        packet.duration = Ffmpeg::av_rescale_q(packet.duration,
codecContext->time_base, data->AudioStream->time_base);
                }

                packet.stream_index = data->AudioStream->index;

                ret = Ffmpeg::av_interleaved_write_frame(data->FormatContext, 
&packet);
                //ret = Ffmpeg::av_write_frame(data->FormatContext, &packet);
                data->AudioWritten++;
        }
                        

        av_packet_unref(&packet);
        got_packet = 0;

        if (ret != 0)
                throw gcnew Exception("Error while writing audio frame.");
}
_______________________________________________
Libav-user mailing list
[email protected]
http://ffmpeg.org/mailman/listinfo/libav-user

Reply via email to