PJMEDIA之录音器的使用(capture sound to avi file)

为熟悉pjmedia相关函数及使用方法,练习了官网上录音器的例子。核心是创建媒体端口将流录制到WAV文件,需正确关闭端口以填充WAV头信息,WAV写入端口支持特定音频格式,指定在标志参数中。

为了熟悉pjmedia的相关函数以及使用方法,这里练习了官网上的一个录音器的例子。

核心函数:

pj_status_t pjmedia_wav_writer_port_create(pj_pool_tpool,
  const char * filename,
  unsigned clock_rate,
  unsigned channel_count,
  unsigned samples_per_frame,
  unsigned bits_per_sample,
  unsigned flags,
  pj_ssize_t buff_size,
  pjmedia_port ** p_port 
 )  

Create a media port to record streams to a WAV file. Note that the port must be closed properly (with pjmedia_port_destroy()) so that the WAV header can be filled with correct values (such as the file length). WAV writer port supports for writing audio in uncompressed 16 bit PCM format or compressed G.711 U-law/A-law format, this needs to be specified in flags param.

Parameters
poolPool to create memory buffers for this port.
filenameFile name.
clock_rateThe sampling rate.
channel_countNumber of channels.
samples_per_frameNumber of samples per frame.
bits_per_sampleNumber of bits per sample (eg 16).
flagsPort creation flags, see pjmedia_file_writer_option.
buff_sizeBuffer size to be allocated. If the value is zero or negative, the port will use default buffer size (which is about 4KB).
p_portPointer to receive the file port instance.
Returns
PJ_SUCCESS on success.
pj_status_t pjmedia_snd_port_create_rec(pj_pool_tpool,
  int index,
  unsigned clock_rate,
  unsigned channel_count,
  unsigned samples_per_frame,
  unsigned bits_per_sample,
  unsigned options,
  pjmedia_snd_port ** p_port 
 )  

Create unidirectional sound device port for capturing audio streams from the sound device with the specified parameters.

Parameters
poolPool to allocate sound port structure.
indexDevice index, or -1 to let the library choose the first available device.
clock_rateSound device's clock rate to set.
channel_countSet number of channels, 1 for mono, or 2 for stereo. The channel count determines the format of the frame.
samples_per_frameNumber of samples per frame.
bits_per_sampleSet the number of bits per sample. The normal value for this parameter is 16 bits per sample.
optionsOptions flag.
p_portPointer to receive the sound device port instance.
Returns
PJ_SUCCESS on success, or the appropriate error code.
pj_status_t pjmedia_endpt_create(pj_pool_factorypf,
  pj_ioqueue_tioqueue,
  unsigned worker_cnt,
  pjmedia_endpt ** p_endpt 
 )  

Create an instance of media endpoint.

Parameters
pfPool factory, which will be used by the media endpoint throughout its lifetime.
ioqueueOptional ioqueue instance to be registered to the endpoint. The ioqueue instance is used to poll all RTP and RTCP sockets. If this argument is NULL, the endpoint will create an internal ioqueue instance.
worker_cntSpecify the number of worker threads to be created to poll the ioqueue.
p_endptPointer to receive the endpoint instance.
Returns
PJ_SUCCESS on success.
pj_status_t pjmedia_snd_port_connect(pjmedia_snd_portsnd_port,
  pjmedia_portport 
 )  

Connect a port to the sound device port. If the sound device port has a sound recorder device, then this will start periodic function call to the port's put_frame() function. If the sound device has a sound player device, then this will start periodic function call to the port's get_frame() function.

For this version of PJMEDIA, the media port MUST have the same audio settings as the sound device port, or otherwise the connection will fail. This means the port MUST have the same clock_rate, channel count, samples per frame, and bits per sample as the sound device port.

Parameters
snd_portThe sound device port.
portThe media port to be connected.
Returns
PJ_SUCCESS on success, or the appropriate error code.
//capture sound to wav file
//heat nan -test
#include<pjmedia.h>
#include<pjlib.h>
#include<stdio.h>
#include<stdlib.h>


#define CLOCK_RATE 44100 //采样率
#define NCHANNELS 2  //通道数
#define SAMPLES_PER_FRAME (NCHANNELS *(CLOCK_RATE*10/1000)) //每帧包含的采样数
#define BITS_PER_SAMPLE 16  //每个抽样的字节数

int main()
{
	pj_caching_pool cp;
	pjmedia_endpt *med_endpt;
	pj_pool_t *pool;
	pjmedia_port *file_port;  
	pjmedia_snd_port *snd_port;
	pj_status_t status;
	char tmp[10];
	char filename[20];

	status=pj_init();
	if(status!=PJ_SUCCESS)
	{
		PJ_LOG(3,("failed","pj_init"));
	}

	pj_caching_pool_init(&cp,&pj_pool_factory_default_policy,0);
//创建endpoint
	status=pjmedia_endpt_create(&cp.factory,NULL,1,&med_endpt);
	if(status!=PJ_SUCCESS)
	{
		PJ_LOG(3,("failed","pjmedia_endpt_create"));
	}

	pool=pj_pool_create(&cp.factory,
		"wav_recoder",4000,4000,NULL);
//输入要保存录音的文件名    
	PJ_LOG(3,("wav_recorder","please input the file name!"));
	gets(filename);
//创建录音端口  把音频流写成wav文件
	status=pjmedia_wav_writer_port_create(pool,filename,
		CLOCK_RATE,
		NCHANNELS,
		SAMPLES_PER_FRAME,
		BITS_PER_SAMPLE,
		0,0,
		&file_port  //指向接收该实例的pjmedia_port
		);
	if(status!=PJ_SUCCESS)
	{
		PJ_LOG(3,("failed","pjmedia_wav_write_port_create"));
	}
//创建单向的音频设备端口用来捕获音频
	status=pjmedia_snd_port_create_rec(pool,-1,
		PJMEDIA_PIA_SRATE(&file_port->info),
		PJMEDIA_PIA_CCNT(&file_port->info),
		PJMEDIA_PIA_SPF(&file_port->info),
		PJMEDIA_PIA_BITS(&file_port->info),
		0,&snd_port);
	if(status!=PJ_SUCCESS)
	{
		PJ_LOG(3,("failed","pjmedia_snd_port_create_rec"));
	}
//连接两个端口开始录音
	status=pjmedia_snd_port_connect(snd_port,file_port);
	if(status!=PJ_SUCCESS)
	{
		PJ_LOG(3,("failed","pjmedia_snd_port_connect"));
	}
 
	pj_thread_sleep(10);
  //显示终止信息  
	puts("PRESS <ENTER> to stop recording and quit");

	if(fgets(tmp,sizeof(tmp),stdin)==NULL)
	{
		puts("EOF while reading stdin,will quit now..");
	}
 //养成良好习惯,吃完饭总要刷刷碗吧! 
	pjmedia_snd_port_destroy(snd_port);
	pjmedia_port_destroy(file_port);

   pj_pool_release(pool);
   pjmedia_endpt_destroy(med_endpt);

   pj_caching_pool_destroy(&cp);

   pj_shutdown();
	return 0;
//	pj_thread_sleep(10);


}

 

转载于:https://www.cnblogs.com/heat-man/p/3664558.html

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值