[Libav-user] Audio file is not getting created.

Prakash Rokade prakash.rokade420 at gmail.com
Thu Feb 9 10:39:31 EET 2017


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.");
}


More information about the Libav-user mailing list