国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Android多媒體功能開發(fā)(11)——使用AudioRecord類錄制音頻

這篇具有很好參考價值的文章主要介紹了Android多媒體功能開發(fā)(11)——使用AudioRecord類錄制音頻。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。

AudioRecord類優(yōu)點(diǎn)是能錄制到緩沖區(qū),能夠?qū)崿F(xiàn)邊錄邊播(AudioRecord + AudioTrack)以及對音頻的實(shí)時處理(如QQ電話)。缺點(diǎn)是輸出是PCM格式的原始采集數(shù)據(jù),如果直接保存成音頻文件,不能夠被播放器播放,所以必須用代碼實(shí)現(xiàn)數(shù)據(jù)編碼以及壓縮。

使用AudioRecord錄音的基本步驟是:確定錄音參數(shù)、申請緩沖區(qū)、創(chuàng)建AudioRecord對象、開始錄制、循環(huán)讀取數(shù)據(jù)到緩沖區(qū)并處理數(shù)據(jù)、停止錄制、釋放資源。

需要確定的錄音參數(shù)包括:采樣率、聲道、格式。申請緩沖區(qū)時需要根據(jù)錄音參數(shù)計算最小緩沖區(qū)大小。有了緩沖區(qū)以后才能創(chuàng)建AudioRecord對象。錄制過程中,需要不停地讀取采樣到的音頻數(shù)據(jù),并進(jìn)行處理。流程和對應(yīng)的代碼如下圖:

Android多媒體功能開發(fā)(11)——使用AudioRecord類錄制音頻

下面編寫一個例子,用AudioRecord采集音頻數(shù)據(jù),并以原始PCM格式存入文件。讀取數(shù)據(jù)和處理數(shù)據(jù)是需要循環(huán)進(jìn)行的操作,所以放入單獨(dú)線程執(zhí)行。例子運(yùn)行在Android8.0以上。

例子界面和主要代碼如下:

Android多媒體功能開發(fā)(11)——使用AudioRecord類錄制音頻

因?yàn)橐浺簦栽谂渲梦募镄枰暶麂浺魴?quán)限。同時,Android將文件寫入應(yīng)用在外部存儲上的私有目錄不需要再申請讀寫存儲的權(quán)限。

<uses-permission android:name="android.permission.RECORD_AUDIO" />


同時,使用AudioRecord錄音需要動態(tài)申請權(quán)限,即在實(shí)際錄音時需要檢查用戶是否允許應(yīng)用使用錄音權(quán)限。如果沒有允許,就彈出一個對話框詢問用戶。代碼如下:

if (ActivityCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
      ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, 1);
      return;
}

這里用到的AudioRecord類的主要方法有:

1)構(gòu)造函數(shù):AudioRecord(int audioSource, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes)?

  • audioSource:音頻來源,一般取麥克風(fēng)MediaRecorder.AudioSource.MIC
  • sampleRateInHz:采樣率
  • channelConfig:聲道配置,一般取AudioFormat.CHANNEL_IN_MONO 、CHANNEL_IN_DEFAULT、CHANNEL_IN_STEREO等
  • audioFormat:音頻格式,取AudioFormat.ENCODING_PCM_16BIT、AudioFormat.ENCODING_PCM_8BIT
  • bufferSizeInBytes:緩沖區(qū)字節(jié)數(shù),不得小于getMinBufferSize計算出的最小緩沖區(qū)大小

2)static int getMinBufferSize(int sampleRateInHz, int channelConfig, int audioFormat):計算最小緩沖區(qū)大小,參數(shù)同構(gòu)造函數(shù)中三個參數(shù)。

3)從硬件讀取音頻數(shù)據(jù)保存到緩沖區(qū)有三個方法,都返回讀取的數(shù)據(jù)個數(shù)

  • int read(byte[] audioData, int offsetInBytes, int sizeInBytes)?
  • int read(ByteBuffer audioBuffer, int sizeInBytes)?
  • int read(short[] audioData, int offsetInShorts, int sizeInShorts)

4)void startRecording():開始錄制

5)void stop():停止錄制

6)void release():釋放資源

從AudioRecord讀取的數(shù)據(jù)是PCM格式,可以用AudioTrack類播放。用AudioTrack類播放音頻的基本流程是:創(chuàng)建AudioTrack對象、開始播放、循環(huán)寫入數(shù)據(jù)到緩沖區(qū)、停止播放、釋放資源。創(chuàng)建AudioTrack對象時需給出參數(shù):采樣率、聲道、格式。流程和對應(yīng)的代碼如下圖:

Android多媒體功能開發(fā)(11)——使用AudioRecord類錄制音頻

下面就為前面的例子加上播放音頻的功能。用AudioTrack播放AudioRecord錄制的PCM音頻文件時需要注意:寫入數(shù)據(jù)后不能馬上release,因?yàn)椴シ攀钱惒降?,此時還剛開始播放,一旦release就不播放了。用AudioTrack還可以實(shí)現(xiàn)變音效果:以采樣率a錄制,以采樣率b播放。主要代碼如下:

Android多媒體功能開發(fā)(11)——使用AudioRecord類錄制音頻

AudioTrack類的主要方法有:

1)構(gòu)造函數(shù):AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes, int mode)?

  • streamType: 流類型,取值為AudioManager.STREAM_VOICE_CALL, AudioManager.STREAM_SYSTEM, AudioManager.STREAM_RING, AudioManager.STREAM_MUSIC, AudioManager.STREAM_ALARM
  • sampleRateInHz:采樣率
  • channelConfig:聲道配置,一般取AudioFormat.CHANNEL_OUT_DEFAULT、CHANNEL_OUT_STEREO等
  • audioFormat:音頻格式,取AudioFormat.ENCODING_PCM_16BIT、AudioFormat.ENCODING_PCM_8BIT
  • bufferSizeInBytes:緩沖區(qū)字節(jié)數(shù),不得小于getMinBufferSize計算出的最小緩沖區(qū)大小
  • mode:緩沖區(qū)類型,MODE_STATIC、MODE_STREAM?

2)void play() :開始播放

3)寫入音頻數(shù)據(jù)到硬件有兩個方法,返回成功寫入的數(shù)據(jù)個數(shù)

  • int write(byte[] audioData, int offsetInBytes, int sizeInBytes)?
  • int write(short[] audioData, int offsetInShorts, int sizeInShorts)?

4)void stop() :停止播放

5)void pause():暫停播放

6)void release():釋放資源

例子的完整代碼如下:

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import android.Manifest;
import android.content.pm.PackageManager;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.*;

import java.io.*;

public class MainActivity extends AppCompatActivity {
    File soundFile;                // 存放錄音的文件
    boolean isRecording;
    int frequency = 11025;
    int inChannelConfig = AudioFormat.CHANNEL_IN_MONO;
    int outChannelConfig = AudioFormat.CHANNEL_OUT_MONO;
    int audioFormat = AudioFormat.ENCODING_PCM_16BIT;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LinearLayout ll = new LinearLayout(this);
        ll.setOrientation(LinearLayout.VERTICAL);
        setContentView(ll);

        //  錄制到文件:Android/data/<package-name>/files/audioRecord.pcm
        soundFile = new File(getExternalFilesDir(null), "audioRecord.pcm");

        Button btnRecord = new Button(this);
        btnRecord.setText("Record");
        ll.addView(btnRecord);
        btnRecord.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                Thread t = new Thread() {
                    public void run() {
                        try {
                            record();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                };
                t.start();
            }
        });
        Button btnStop = new Button(this);
        btnStop.setText("Stop");
        ll.addView(btnStop);
        btnStop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                isRecording = false;
            }
        });

        Button btnPlay = new Button(this);
        btnPlay.setText("Play");
        ll.addView(btnPlay);
        btnPlay.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                if (soundFile.exists()) {
                    try {
                        play(frequency);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        });

        Button btnPlayFast = new Button(this);
        btnPlayFast.setText("Play Fast");
        ll.addView(btnPlayFast);
        btnPlayFast.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                if (soundFile.exists()) {
                    try {
                        play(frequency * 4 / 3);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        });

        Button btnPlaySlow = new Button(this);
        btnPlaySlow.setText("Play Slow");
        ll.addView(btnPlaySlow);
        btnPlaySlow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                if (soundFile.exists()) {
                    try {
                        play(frequency * 3 / 4);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        });

        Button btnSpeak = new Button(this);
        btnSpeak.setText("Press to Speak");
        ll.addView(btnSpeak);
        btnSpeak.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View arg0, MotionEvent arg1) {
                switch (arg1.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        Thread t = new Thread() {
                            public void run() {
                                try {
                                    record();
                                } catch (IOException e) {
                                    e.printStackTrace();
                                }
                            }
                        };
                        t.start();
                        break;
                    case MotionEvent.ACTION_UP:
                        isRecording = false;
                        break;
                }
                return false;
            }
        });
    }

    void record() throws IOException {
        // 動態(tài)權(quán)限申請
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, 1);
            return;
        }

        if (soundFile.exists()) soundFile.delete();
        soundFile.createNewFile();

        FileOutputStream fos = new FileOutputStream(soundFile);
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        DataOutputStream dos = new DataOutputStream(bos);

        int bufferSize = AudioRecord.getMinBufferSize(frequency, inChannelConfig, audioFormat);
        short[] buffer = new short[bufferSize];
        AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, frequency, inChannelConfig, audioFormat, bufferSize);

        audioRecord.startRecording();
        isRecording = true;
        while(isRecording){
            int bufferRead = audioRecord.read(buffer, 0, bufferSize);
            for(int i=0; i<bufferRead; i++){
                dos.writeShort(buffer[i]);
            }
        }
        audioRecord.stop();
        audioRecord.release();

        dos.close();
        bos.close();
        fos.close();
    }

    void play(int frq) throws IOException{
        int length = (int)soundFile.length()/2;
        if(!soundFile.exists() || length==0) {
            Toast.makeText(getBaseContext(), "音頻文件不存在或?yàn)榭?, Toast.LENGTH_SHORT).show();
            return;
        }
        short[] data = new short[length];
        FileInputStream fis = new FileInputStream(soundFile);
        BufferedInputStream bis = new BufferedInputStream(fis);
        DataInputStream dis = new DataInputStream(bis);
        int i=0;
        while(dis.available()>0) {
            data[i] = dis.readShort();
            i++;
        }
        dis.close();
        bis.close();
        fis.close();

        AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, frq, outChannelConfig, audioFormat, length*2, AudioTrack.MODE_STREAM);
        audioTrack.play();
        audioTrack.write(data, 0, length);
        audioTrack.stop();
        //audioTrack.release();		// 不能馬上release,因?yàn)閣rite后是異步播放,此時還剛開始播放,release就不播放了
    }
}

Android多媒體功能開發(fā)-使用AudioRecord類錄制音頻的例子?文章來源地址http://www.zghlxwxcb.cn/news/detail-407146.html

到了這里,關(guān)于Android多媒體功能開發(fā)(11)——使用AudioRecord類錄制音頻的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • HarmonyOS學(xué)習(xí)路之開發(fā)篇—多媒體開發(fā)(圖像開發(fā) 二)

    圖像編碼就是將PixelMap圖像編碼成不同存檔格式圖片,用于后續(xù)其他處理,比如保存、傳輸?shù)取.?dāng)前僅支持JPEG格式。 ImagePacker主要用于圖像編碼。 接口名 描述 create() 創(chuàng)建圖像打包器實(shí)例。 initializePacking(byte[] data, PackingOptions opts) 初始化打包任務(wù),將字節(jié)數(shù)組設(shè)置為打包后輸

    2024年02月11日
    瀏覽(97)
  • HarmonyOS學(xué)習(xí)路之開發(fā)篇—多媒體開發(fā)(圖像開發(fā) 一)

    HarmonyOS圖像模塊支持圖像業(yè)務(wù)的開發(fā),常見功能如圖像解碼、圖像編碼、基本的位圖操作、圖像編輯等。當(dāng)然,也支持通過接口組合來實(shí)現(xiàn)更復(fù)雜的圖像處理邏輯。 圖像解碼 圖像解碼就是不同的存檔格式圖片(如JPEG、PNG等)解碼為無壓縮的位圖格式,以方便在應(yīng)用或者系統(tǒng)

    2024年02月11日
    瀏覽(87)
  • HarmonyOS學(xué)習(xí)路之開發(fā)篇—多媒體開發(fā)(相機(jī)開發(fā) 一)

    HarmonyOS學(xué)習(xí)路之開發(fā)篇—多媒體開發(fā)(相機(jī)開發(fā) 一)

    HarmonyOS相機(jī)模塊支持相機(jī)業(yè)務(wù)的開發(fā),開發(fā)者可以通過已開放的接口實(shí)現(xiàn)相機(jī)硬件的訪問、操作和新功能開發(fā),最常見的操作如:預(yù)覽、拍照、連拍和錄像等。 相機(jī)靜態(tài)能力 用于描述相機(jī)的固有能力的一系列參數(shù),比如朝向、支持的分辨率等信息。 物理相機(jī) 物理相機(jī)就是獨(dú)

    2024年02月10日
    瀏覽(91)
  • HarmonyOS學(xué)習(xí)路之開發(fā)篇—多媒體開發(fā)(相機(jī)開發(fā) 二)

    Camera操作類,包括相機(jī)預(yù)覽、錄像、拍照等功能接口。 接口名 描述 triggerSingleCapture?(FrameConfig frameConfig) 啟動相機(jī)幀的單幀捕獲。 triggerMultiCapture?(ListFrameConfig frameConfigs) 啟動相機(jī)幀的多幀捕獲。 configure?(CameraConfig config) 配置相機(jī)。 flushCaptures?() 停止并清除相機(jī)幀的捕獲

    2024年02月11日
    瀏覽(91)
  • Ubuntu 多媒體播放器——KMPlayer Linux:功能強(qiáng)大的視頻播放工具

    KMPlayer Linux是一款功能強(qiáng)大的多媒體播放器,專為Ubuntu操作系統(tǒng)設(shè)計。它提供了豐富的功能和用戶友好的界面,使得在Ubuntu上觀看視頻變得更加方便和愉快。本文將介紹KMPlayer Linux的安裝過程,并提供一些示例代碼來演示其功能。 安裝KMPlayer Linux 要安裝KMPlayer Linux,請按照以下

    2024年02月04日
    瀏覽(132)
  • qt6 多媒體開發(fā)代碼分析(二、錄音)

    常見的音頻編碼格式包括MP3、AAC、OGG、WMA、FLAC等,它們之間具有以下區(qū)別: 編碼方式不同:這些編碼格式采用的編碼算法不同,例如MP3和AAC使用有損壓縮算法,而FLAC使用無損壓縮算法。 壓縮率和文件大小不同:由于采用的編碼算法不同,不同格式的音頻文件壓縮率和文件大

    2024年02月07日
    瀏覽(17)
  • HarmonyOS學(xué)習(xí)路之開發(fā)篇—多媒體開發(fā)(音頻開發(fā) 二(1)

    HarmonyOS學(xué)習(xí)路之開發(fā)篇—多媒體開發(fā)(音頻開發(fā) 二(1)

    接口說明 接口名 描述 AudioCapturer(AudioCapturerInfo audioCapturerInfo) throws IllegalArgumentException 構(gòu)造函數(shù),設(shè)置錄音相關(guān)音頻參數(shù),使用默認(rèn)錄音設(shè)備。 AudioCapturer(AudioCapturerInfo audioCapturerInfo, AudioDeviceDescriptor devInfo) throws IllegalArgumentException 構(gòu)造函數(shù),設(shè)置錄音相關(guān)音頻參數(shù)并指定錄音

    2024年04月23日
    瀏覽(98)
  • SDL庫入門:掌握跨平臺游戲開發(fā)和多媒體編程

    SDL (Simple DirectMedia Layer) 是一個跨平臺的開源多媒體庫,它提供了訪問音頻、鍵盤、鼠標(biāo)、操縱桿以及圖形硬件的底層接口。SDL 可用于開發(fā)游戲、仿真器、媒體播放器等多種類型的應(yīng)用程序。 1.1 SDL 的背景與應(yīng)用領(lǐng)域 SDL 由 Sam Lantinga 開發(fā),最早發(fā)布于 1998 年。SDL 的設(shè)計目標(biāo)是

    2024年02月02日
    瀏覽(23)
  • [任務(wù)書+論文+PPT+源碼]基于Android與多媒體的英文學(xué)習(xí)APP的設(shè)計與實(shí)現(xiàn)

    [任務(wù)書+論文+PPT+源碼]基于Android與多媒體的英文學(xué)習(xí)APP的設(shè)計與實(shí)現(xiàn)

    第1頁 畢業(yè)設(shè)計(論文)題目:基于ANDROID與多媒體技術(shù)的英文學(xué)習(xí)APP的設(shè)計與實(shí)現(xiàn)設(shè)計(論文)要求及原始數(shù)據(jù)(資料):1.綜述國內(nèi)外移動互聯(lián)現(xiàn)狀及前景;2.了解ANDROID系統(tǒng),理解ANDROID應(yīng)用程序的開發(fā)方法和步驟;3.分析該ANDROID應(yīng)用程序的模塊結(jié)構(gòu)和主要算法;4.熟悉

    2024年01月22日
    瀏覽(23)
  • 【C++】開源:多媒體SFML庫使用入門

    【C++】開源:多媒體SFML庫使用入門

    ?? ★,° :.☆( ̄▽ ̄)/$: .°★ ?? 這篇文章主要介紹SFML庫使用。 學(xué)其所用,用其所學(xué)?!簡⒊?歡迎來到我的博客,一起學(xué)習(xí)知識,共同進(jìn)步。 喜歡的朋友可以關(guān)注一下,下次更新不迷路?? SFML (Simple and Fast Multimedia Library) 是一個開源的、跨平臺的C++多媒體庫,它提供了

    2024年02月16日
    瀏覽(22)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包