demo簡(jiǎn)介
iApp要想實(shí)現(xiàn)邊錄邊聽(tīng)功能就不能使用iApp帶有的bly來(lái)進(jìn)行錄音甘凭。
既然iApp的代碼不能滿足我們裕偿,我們就使用Android SDK來(lái)滿足自己宪赶!
利用AndroidSDK提供的AudioRecord來(lái)進(jìn)行錄音采樣就能獲取音頻的裸流栈幸。
實(shí)現(xiàn)了錄音,我們還有一個(gè)播放音頻這時(shí)候難道要用iApp提供的bfm嗎嵌牺?
我們可以使用AndroidSDK提供的AudioTrack來(lái)播放錄下來(lái)的聲音打洼。
話就不多說(shuō)了下面就開(kāi)始敲代碼吧!喵~
mian載入事件code
//錄音緩存文件
ss audiotmpfile = "/sdcard/RecordAudioFile/audio_tmp.pcm"
//錄音保存文件
ss audiosavefile = "/sdcard/RecordAudioFile/audio.wav"
//音源 0.默認(rèn) 1.是麥克風(fēng) 5.相機(jī)前置麥克風(fēng) 8.揚(yáng)聲器
ss audiosource = 1
//采樣率 48000-4000Hz
ss sampleRateInHz = 44100
//通道 12.雙通道 2.單通道 4.左通道 8.右通道; (通道指耳機(jī)的左和右)立體音
ss channel = 12
//音頻數(shù)據(jù)格式 2.16bit 3.8bit
ss audioformat = 2
//計(jì)算采樣的緩沖區(qū)大小
java(ss.samplebuffersize,null,"android.media.AudioRecord.getMinBufferSize","int",ss.sampleRateInHz,"int",2,"int",ss.audioformat)
//------視圖單機(jī)監(jiān)聽(tīng)
cls("android.view.View$OnClickListener",c)
ss type = 0
javacb(hd,c)
{
sgsz(st_aS,0,view)
java(index,ss.ids,"java.util.ArrayList.indexOf","Object",view)
f(index==0)
{
//效果按鈕
ug(view,"text",text)
f(text=="效果(普通)")
{
us(view,"text","效果(反聽(tīng))")
ss type = 1
}
else
{
us(view,"text","效果(普通)")
ss type = 0
}
}
else f(index==1)
{
//錄音按鈕
fn lly.createAudioRecord(ss.sampleRateInHz)
f(ss.type==0)
{
fn lly.startRecord(ss.audioRecord,ss.samplebuffersize,ss.audiotmpfile)
}
else f(ss.type==1)
{
fn lly.createAudioTrack(ss.sampleRateInHz)
fn lly.startRecord(ss.audioRecord,ss.track,ss.samplebuffersize,ss.audiotmpfile)
}
}
else f(index==2)
{
//暫停按鈕
ug(view,"text",text)
f(text=="暫停錄音")
{
fn lly.pauseRecord();
us(view,"text","繼續(xù)錄音")
}
else
{
us(view,"text","暫停錄音")
gslist(ss.ids,1,view)
java(null,view,"android.view.View.performClick")
}
}
else f(index==3)
{
//停止按鈕
fn lly.stopRecord(ss.audioRecord,ss.track,ss.audiotmpfile,ss.audiosavefile)
tw("已保存錄音文件")
}
else f(index==4)
{
//播放按鈕
fn lly.AudioPlay(ss.audiosavefile)
}
f(ss.error!=null)
{
syso(ss.error)
tw(ss.error)
ss error = null
}
}
//------視圖單機(jī)監(jiān)聽(tīng)------
//------放置按鈕--------
sl("效果(普通)|開(kāi)始錄音|暫停錄音|停止錄音|播放錄音","|",bntexts)
for(str;bntexts)
{
nvw(3,1,"按鈕","width=-2\nheight=-2\ntext="+str,bn)
java(null,bn,"android.view.View.setOnClickListener","android.view.View$OnClickListener",hd)
aslist(ss.ids,bn)
}
//------放置按鈕--------
fn函數(shù)庫(kù)
先新建一個(gè)lly.myu逆粹,把下面的copy進(jìn)去募疮。
剩下的操作直接調(diào)用就行了!
反聽(tīng)效果有一個(gè)問(wèn)題 AudioRecord讀取數(shù)據(jù)需要150ms左右然后用AudioTrack寫入也需要150ms左右造成了300ms左右才有聲音的延遲僻弹。
//創(chuàng)建AudioRecord對(duì)象
fn createAudioRecord(samplebuffersize)
javanew(ss.audioRecord,"android.media.AudioRecord","int",1,"int",ss.sampleRateInHz,"int",12,"int",2,"int",samplebuffersize)
end fn
//創(chuàng)建AudioTrack對(duì)象
fn createAudioTrack(samplebuffersize)
javanew(ss.track,"android.media.AudioTrack","int",3,"int",ss.sampleRateInHz,"int",12,"int",2,"int",samplebuffersize,"int",1)
//java(null,ss.track,"android.media.AudioTrack.play")
end fn
//開(kāi)始普通錄音
fn startRecord(audiorecord,samplebuffersize,filepath)
f(ss.isRecord)
{
ss error = "method:startRecord message:Recording"
endcode
}
t()
{
fn lly.AudioRecordWriteStream(audiorecord,samplebuffersize,filepath)
}
ss isRecord = true
end fn
//開(kāi)始帶反音效果錄制
fn startRecord(audiorecord,audiotrack,samplebuffersize,filepath)
f(ss.isRecord)
{
ss error = "method:startRecord message:Recording"
endcode
}
t()
{
fn lly.ReturnBackAudioWriteStream(audiorecord,audiotrack,samplebuffersize,filepath)
}
ss isRecord = true
end fn
//暫停錄音(可以不調(diào)用本函數(shù) 直接使用(ss isRecord = false)即可;
fn pauseRecord()
ss isRecord = false
end fn
//停止錄音
fn stopRecord(audiorecord,audiotrack,filepath,newfilepath)
ss isRecord = false
java(null,audiorecord,"android.media.AudioRecord.release")
f(ss.audiotrack!=null)
{
java(null,audiotrack,"android.media.AudioTrack.release")
}
fn lly.pcmDataAddHeader(filepath,newfilepath)
end fn
//輸出普通音頻到文件里
fn AudioRecordWriteStream(audiorecord,samplebuffersize,filepath)
cls("byte",c)
//------創(chuàng)建目錄和文件------
javanew(file,"java.io.File","String",filepath)
java(filep,file,"java.io.File.getParentFile")
java(iserror,filep,"java.io.File.mkdirs")
java(iserror,file,"java.io.File.createNewFile")
//------創(chuàng)建目錄和文件------
//創(chuàng)建追加輸出流
javanew(os,"java.io.FileOutputStream","java.io.File",file,"boolean",true)
java(bytes,null,"java.lang.reflect.Array.newInstance","java.lang.Class",c,"int",samplebuffersize)
//開(kāi)始錄音
java(null,audiorecord,"android.media.AudioRecord.startRecording")
//讀取采樣數(shù)據(jù)
java(state,audiorecord,"android.media.AudioRecord.read","byte[]",bytes,"int",0,"int",samplebuffersize)
w(state!=-3&&ss.isRecord)
{
java(state,audiorecord,"android.media.AudioRecord.read","byte[]",bytes,"int",0,"int",samplebuffersize)
java(null,os,"java.io.OutputStream.write","byte[]",bytes,"int",0,"int",samplebuffersize)
}
java(null,os,"java.io.OutputStream.close")
java(null,audiorecord,"android.media.AudioRecord.stop")
end fn
//輸出帶反音音頻到文件里
fn ReturnBackAudioWriteStream(audiorecord,audiotrack,samplebuffersize,filepath)
cls("byte",c)
//------創(chuàng)建目錄和文件------
javanew(file,"java.io.File","String",filepath)
java(filep,file,"java.io.File.getParentFile")
java(iserror,filep,"java.io.File.mkdirs")
java(iserror,file,"java.io.File.createNewFile")
//------創(chuàng)建目錄和文件------
//創(chuàng)建追加輸出流
javanew(os,"java.io.FileOutputStream","java.io.File",file,"boolean",true)
//播放回音
java(null,audiotrack,"android.media.AudioTrack.play")
java(bytes,null,"java.lang.reflect.Array.newInstance","java.lang.Class",c,"int",samplebuffersize)
//開(kāi)始錄音
java(null,audiorecord,"android.media.AudioRecord.startRecording")
//讀取采樣數(shù)據(jù)
java(state,audiorecord,"android.media.AudioRecord.read","byte[]",bytes,"int",0,"int",samplebuffersize)
w(state!=-3&&ss.isRecord)
{
java(state,audiorecord,"android.media.AudioRecord.read","byte[]",bytes,"int",0,"int",samplebuffersize)
java(null,audiotrack,"android.media.AudioTrack.write","byte[]",bytes,"int",0,"int",samplebuffersize)
java(null,os,"java.io.OutputStream.write","byte[]",bytes,"int",0,"int",samplebuffersize)
}
//關(guān)閉輸出流
java(null,os,"java.io.OutputStream.close")
//在這里暫停是為了防止用戶按下停止時(shí)AudioRevord還在采樣但已經(jīng)停止工作會(huì)結(jié)束當(dāng)前函數(shù)酝锅,所以要吧關(guān)閉輸出流寫在他們上面!
java(null,audiorecord,"android.media.AudioRecord.stop")
java(null,audiotrack,"android.media.AudioTrack.pause")
end fn
//給裸流添加頭數(shù)據(jù)(因?yàn)閕App沒(méi)辦法使用一些運(yùn)算符所以這里的數(shù)據(jù)是固定的所以可能會(huì)照成無(wú)法播放)
fn pcmDataAddHeader(filepath,newfilepath)
//------創(chuàng)建目錄和文件------
javanew(file,"java.io.File","String",filepath)
javanew(newfile,"java.io.File","String",newfilepath)
java(filep,newfile,"java.io.File.getParentFile")
java(iserror,filep,"java.io.File.mkdirs")
java(iserror,newfile,"java.io.File.createNewFile")
//------創(chuàng)建目錄和文件------
javanew(is,"java.io.FileInputStream","java.io.File",file)
javanew(os,"java.io.FileOutputStream","java.io.File",newfile)
//頭數(shù)據(jù)
s a = "82 73 70 70 36 115 248 0 87 65 86 69 102 109 116 32 16 0 0 0 1 0 2 0 68 172 0 0 16 177 2 0 4 0 16 0 100 97 116 97 0 115 248 0"
sl(a," ",b)
//輸出44位頭數(shù)據(jù)
for(c;b)
{
s(c+0,c)
java(null,os,"java.io.OutputStream.write","int",c)
}
java(len,is,"java.io.InputStream.available")
cls("byte",c)
java(bytes,null,"java.lang.reflect.Array.newInstance","java.lang.Class",c,"int",len)
//拷貝裸數(shù)據(jù)進(jìn)來(lái)
java(len,is,"java.io.InputStream.read","byte[]",bytes,"int",0,"int",len)
java(null,os,"java.io.OutputStream.write","byte[]",bytes,"int",0,"int",len)
java(null,os,"java.io.OutputStream.close")
end fn
//播放音頻
fn AudioPlay(filepath)
bfm(filepath,ss.mp)
bfms(ss.mp,"st")
bfms(ss.mp,"sl",true)
bfms(ss.mp, "ip", c)
f(!c)
{
ss error = "method:AudioPlay message:PlayError"
endcode
}
utw(null,"AudioPlayer","alertwindow.iyu","exit",true,v)
{
bfms(ss.mp, "sp")
bfms(ss.mp, "re")
ss mp = null
}
gvs(v,2,ss.vp)
gvs(v,3,ss.vt)
gvs(v,4,ss.vtt)
bfms(ss.mp, "dn", dn)
us(ss.vp,"max",dn)
fn lly.timetoformat(dn)
us(ss.vtt,"text",ss.timeformat)
ssj(ss.vp,"touchmonitor")
{
ug(st_vW,"progress",ps)
bfms(ss.mp, "seekto", ps)
}
t()
{
w(ss.mp!=null)
{
ufnsui()
{
bfms(ss.mp, "cn", cdn)
us(ss.vp,"progress",cdn)
fn lly.timetoformat(cdn)
us(ss.vt,"text",ss.timeformat)
}
stop(1000)
}
}
end fn
//給時(shí)間加格式
fn timetoformat(num)
s(num/1000/60,m)
s(num/1000%60,s)
f(m<10)
{
ss("0"+m,m)
}
f(s<10)
{
ss("0"+s,s)
}
ss(m+":"+s,ss.timeformat)
end fn
源碼下載(本接口不經(jīng)常開(kāi)啟)
入群下載(如果無(wú)法跳轉(zhuǎn)請(qǐng)復(fù)制群號(hào))
Q群:947756726