日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > Android >内容正文

Android

Android音频开发

發(fā)布時(shí)間:2023/12/31 Android 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android音频开发 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

這篇博客 轉(zhuǎn)載自 https://www.jianshu.com/p/c0222de2faed

這里涉及到ndk的一些知識(shí),對(duì)于.mk文件不太熟悉的同學(xué)要自己去 官網(wǎng) 或者搜索一些博客了解基本知識(shí)。

Android音頻開(kāi)發(fā)

  • 1. 音頻基礎(chǔ)知識(shí)
    • 音頻基礎(chǔ)知識(shí)
    • 常用音頻格式
    • 音頻開(kāi)發(fā)的主要應(yīng)用
    • 音頻開(kāi)發(fā)的具體內(nèi)容
  • 2. 使用AudioRecord錄制pcm格式音頻
    • AudioRecord類(lèi)的介紹
    • 實(shí)現(xiàn)
    • 其他
  • 3. 使用AudioRecord實(shí)現(xiàn)錄音的暫停和恢復(fù)
    • 解決辦法
    • 實(shí)現(xiàn)
    • 其他
  • 4. PCM轉(zhuǎn)WAV格式音頻
    • wav 和 pcm
    • WAV頭文件
    • java 生成頭文件
    • PCM轉(zhuǎn)Wav
    • 參考鏈接:
  • 5. Mp3的錄制 - 編譯Lame源碼
    • 編譯 so包
    • 編譯
  • 6. Mp3的錄制 - 使用Lame實(shí)時(shí)錄制MP3格式音頻
    • 前言
    • 代碼實(shí)現(xiàn)
    • 使用
  • 7. 音樂(lè)可視化-FFT頻譜圖
    • 實(shí)現(xiàn)
    • 準(zhǔn)備工作
    • 開(kāi)始播放
    • 使用可視化類(lèi)Visualizer獲取當(dāng)前音頻數(shù)據(jù)
    • 編寫(xiě)自定義控件,展示數(shù)據(jù)

1. 音頻基礎(chǔ)知識(shí)

音頻基礎(chǔ)知識(shí)

采樣和采樣頻率:
現(xiàn)在是數(shù)字時(shí)代,在音頻處理時(shí)要先把音頻的模擬信號(hào)變成數(shù)字信號(hào),這叫A/D轉(zhuǎn)換。要把音頻的模擬信號(hào)變成數(shù)字信號(hào),就需要采樣。一秒鐘內(nèi)采樣的次數(shù)稱(chēng)為采樣頻率

采樣頻率越高,越接近原始信號(hào),但是也加大了運(yùn)算處理的復(fù)雜度。16000Hz和44.1kHZ(1

采樣位數(shù)/位寬:
數(shù)字信號(hào)是用0和1來(lái)表示的。采樣位數(shù)就是采樣值用多少位0和1來(lái)表示,也叫采樣精度,用的位數(shù)越多就越接近真實(shí)聲音。如用8位表示,采樣值取值范圍就是-128 ~ 127,如用16位表示,采樣值取值范圍就是-32768 ~ 32767。

聲道(channel):
通常語(yǔ)音只用一個(gè)聲道。而對(duì)于音樂(lè)來(lái)說(shuō),既可以是單聲道(mono),也可以是雙聲道(即左聲道右聲道,叫立體聲stereo),還可以是多聲道,叫環(huán)繞立體聲。

編解碼 :
通常把音頻采樣過(guò)程也叫做脈沖編碼調(diào)制編碼,即PCM(Pulse Code Modulation)編碼,采樣值也叫PCM值。 如果把采樣值直接保存或者發(fā)送,會(huì)占用很大的存儲(chǔ)空間。以16kHz采樣率16位采樣位數(shù)單聲道為例,一秒鐘就有16/8*16000 = 32000字節(jié)。為了節(jié)省保存空間或者發(fā)送流量,會(huì)對(duì)PCM值壓縮。

目前主要有三大技術(shù)標(biāo)準(zhǔn)組織制定壓縮標(biāo)準(zhǔn):

  • ITU,主要制定有線(xiàn)語(yǔ)音的壓縮標(biāo)準(zhǔn)(g系列),有g(shù)711/g722/g726/g729等。
  • 3GPP,主要制定無(wú)線(xiàn)語(yǔ)音的壓縮標(biāo)準(zhǔn)(amr系列等),有amr-nb/amr-wb。后來(lái)ITU吸納了amr-wb,形成了g722.2。
  • MPEG,主要制定音樂(lè)的壓縮標(biāo)準(zhǔn),有11172-3,13818-3/7,14496-3等。
    一些大公司或者組織也制定壓縮標(biāo)準(zhǔn),比如iLBC,OPUS。
  • 編碼過(guò)程:模擬信號(hào)->抽樣->量化->編碼->數(shù)字信號(hào)

    壓縮:
    對(duì)于自然界中的音頻信號(hào),如果轉(zhuǎn)換成數(shù)字信號(hào),進(jìn)行音頻編碼,那么只能無(wú)限接近,不可能百分百還原。所以說(shuō)實(shí)際上任何信號(hào)轉(zhuǎn)換成數(shù)字信號(hào)都會(huì)“有損”。但是在計(jì)算機(jī)應(yīng)用中,能夠達(dá)到最高保真水平的就是PCM編碼。因此,PCM約定俗成了無(wú)損編碼。我們而習(xí)慣性的把MP3列入有損音頻編碼范疇,是相對(duì)PCM編碼的。強(qiáng)調(diào)編碼的相對(duì)性的有損和無(wú)損

    碼率:
    碼率 = 采樣頻率 * 采樣位數(shù) * 聲道個(gè)數(shù); 例:采樣頻率44.1KHz,量化位數(shù)16bit,立體聲(雙聲道),未壓縮時(shí)的碼率 = 44.1KHz * 16 * 2 = 1411.2Kbps = 176.4KBps,即每秒要錄制的資源大小,理論上碼率和質(zhì)量成正比。

    800 bps – 能夠分辨的語(yǔ)音所需最低碼率(需使用專(zhuān)用的FS-1015語(yǔ)音編解碼器) 8 kbps —電話(huà)質(zhì)量(使用語(yǔ)音編碼) 8-500 kbps --Ogg Vorbis和MPEG1 Player1/2/3中使用的有損音頻模式 500 kbps–1.4 Mbps —44.1KHz的無(wú)損音頻,解碼器為FLAC Audio,WavPack或Monkey's Audio 1411.2 - 2822.4 Kbps —脈沖編碼調(diào)制(PCM)聲音格式CD光碟的數(shù)字音頻 5644.8 kbps —SACD使用的Direct Stream Digital格式

    常用音頻格式

    WAV 格式:音質(zhì)高 無(wú)損格式 體積較大
    AAC(Advanced Audio Coding) 格式:相對(duì)于 mp3,AAC 格式的音質(zhì)更佳,文件更小,有損壓縮,一般蘋(píng)果或者Android SDK4.1.2(API 16)及以上版本支持播放,性?xún)r(jià)比高
    AMR 格式:壓縮比比較大,但相對(duì)其他的壓縮格式質(zhì)量比較差,多用于人聲,通話(huà)錄音

    AMR分類(lèi): AMR(AMR-NB): 語(yǔ)音帶寬范圍:3003400Hz,8KHz抽樣

    mp3 格式:特點(diǎn) 使用廣泛, 有損壓縮,犧牲了12KHz到16KHz高音頻的音質(zhì)

    音頻開(kāi)發(fā)的主要應(yīng)用

    • 音頻播放器
    • 錄音機(jī)
    • 語(yǔ)音電話(huà)
    • 音視頻監(jiān)控應(yīng)用
    • 音視頻直播應(yīng)用
    • 音頻編輯/處理軟件(ktv音效、變聲, 鈴聲轉(zhuǎn)換)
    • 藍(lán)牙耳機(jī)/音箱

    音頻開(kāi)發(fā)的具體內(nèi)容

    • 音頻采集/播放
    • 音頻算法處理(去噪、靜音檢測(cè)、回聲消除、音效處理、功放/增強(qiáng)、混音/分離,等等)
    • 音頻的編解碼和格式轉(zhuǎn)換
    • 音頻傳輸協(xié)議的開(kāi)發(fā)(SIP,A2DP、AVRCP,等等)

    2. 使用AudioRecord錄制pcm格式音頻

    AudioRecord類(lèi)的介紹

    1. AudioRecord構(gòu)造函數(shù):

    /*** @param audioSource :錄音源* 這里選擇使用麥克風(fēng):MediaRecorder.AudioSource.MIC* @param sampleRateInHz: 采樣率* @param channelConfig:聲道數(shù) * @param audioFormat: 采樣位數(shù).* See {@link AudioFormat#ENCODING_PCM_8BIT}, {@link AudioFormat#ENCODING_PCM_16BIT},* and {@link AudioFormat#ENCODING_PCM_FLOAT}.* @param bufferSizeInBytes: 音頻錄制的緩沖區(qū)大小* See {@link #getMinBufferSize(int, int, int)} */ public AudioRecord(int audioSource, int sampleRateInHz, int channelConfig, int audioFormat,int bufferSizeInBytes)

    2. getMinBufferSize()

    /** * 獲取AudioRecord所需的最小緩沖區(qū)大小 * @param sampleRateInHz: 采樣率 * @param channelConfig:聲道數(shù) * @param audioFormat: 采樣位數(shù). */ public static int getMinBufferSize (int sampleRateInHz, int channelConfig, int audioFormat)

    3. getRecordingState()

    /** * 獲取AudioRecord當(dāng)前的錄音狀態(tài) * @see AudioRecord#RECORDSTATE_STOPPED * @see AudioRecord#RECORDSTATE_RECORDING */ public int getRecordingState()

    4. startRecording()

    /*** 開(kāi)始錄制*/public int startRecording()

    5. stop()

    /*** 停止錄制*/public int stop()

    6. read()

    /*** 從錄音設(shè)備中讀取音頻數(shù)據(jù)* @param audioData 音頻數(shù)據(jù)寫(xiě)入的byte[]緩沖區(qū)* @param offsetInBytes 偏移量* @param sizeInBytes 讀取大小* @return 返回負(fù)數(shù)則表示讀取失敗* see {@link #ERROR_INVALID_OPERATION} -3 : 初始化錯(cuò)誤{@link #ERROR_BAD_VALUE} -3: 參數(shù)錯(cuò)誤{@link #ERROR_DEAD_OBJECT} -6: {@link #ERROR} */ public int read(@NonNull byte[] audioData, int offsetInBytes, int sizeInBytes)

    實(shí)現(xiàn)

    實(shí)現(xiàn)過(guò)程就是調(diào)用上面的API的方法,構(gòu)造AudioRecord實(shí)例后再調(diào)用startRecording(),開(kāi)始錄音,并通過(guò)read()方法不斷獲取錄音數(shù)據(jù)記錄下來(lái),生成PCM文件。涉及耗時(shí)操作,所以最好在子線(xiàn)程中進(jìn)行。

    public class RecordHelper {//0.此狀態(tài)用于控制線(xiàn)程中的循環(huán)操作,應(yīng)用volatile修飾,保持?jǐn)?shù)據(jù)的一致性private volatile RecordState state = RecordState.IDLE;private AudioRecordThread audioRecordThread;private File tmpFile = null;public void start(String filePath, RecordConfig config) {if (state != RecordState.IDLE) {Logger.e(TAG, "狀態(tài)異常當(dāng)前狀態(tài): %s", state.name());return;}recordFile = new File(filePath);String tempFilePath = getTempFilePath();Logger.i(TAG, "tmpPCM File: %s", tempFilePath);tmpFile = new File(tempFilePath);//1.開(kāi)啟錄音線(xiàn)程并準(zhǔn)備錄音audioRecordThread = new AudioRecordThread();audioRecordThread.start();}public void stop() {if (state == RecordState.IDLE) {Logger.e(TAG, "狀態(tài)異常當(dāng)前狀態(tài): %s", state.name());return;}state = RecordState.STOP;}private class AudioRecordThread extends Thread {private AudioRecord audioRecord;private int bufferSize;AudioRecordThread() {//2.根據(jù)錄音參數(shù)構(gòu)造AudioRecord實(shí)體對(duì)象bufferSize = AudioRecord.getMinBufferSize(currentConfig.getFrequency(),currentConfig.getChannel(), currentConfig.getEncoding()) * RECORD_AUDIO_BUFFER_TIMES;audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, currentConfig.getFrequency(),currentConfig.getChannel(), currentConfig.getEncoding(), bufferSize);}@Overridepublic void run() {super.run();state = RecordState.RECORDING;Logger.d(TAG, "開(kāi)始錄制");FileOutputStream fos = null;try {fos = new FileOutputStream(tmpFile);audioRecord.startRecording();byte[] byteBuffer = new byte[bufferSize];while (state == RecordState.RECORDING) {//3.不斷讀取錄音數(shù)據(jù)并保存至文件中int end = audioRecord.read(byteBuffer, 0, byteBuffer.length);fos.write(byteBuffer, 0, end);fos.flush();}//4.當(dāng)執(zhí)行stop()方法后state != RecordState.RECORDING,終止循環(huán),停止錄音audioRecord.stop();} catch (Exception e) {Logger.e(e, TAG, e.getMessage());} finally {try {if (fos != null) {fos.close();}} catch (IOException e) {Logger.e(e, TAG, e.getMessage());}}state = RecordState.IDLE;Logger.d(TAG, "錄音結(jié)束");}} }

    其他

    • 這里實(shí)現(xiàn)了PCM音頻的錄制,AudioRecord
      API中只有開(kāi)始和停止的方法,在實(shí)際開(kāi)發(fā)中可能還需要暫停/恢復(fù)的操作,以及PCM轉(zhuǎn)WAV的功能,下一篇再繼續(xù)完善。
    • 需要錄音及文件處理的動(dòng)態(tài)權(quán)限

    3. 使用AudioRecord實(shí)現(xiàn)錄音的暫停和恢復(fù)

    上一部分主要寫(xiě)了AudioRecord實(shí)現(xiàn)音頻錄制的開(kāi)始和停止,AudioRecord并沒(méi)有暫停和恢復(fù)播放功能的API,所以需要手動(dòng)實(shí)現(xiàn)。

    解決辦法

    思路很簡(jiǎn)單,現(xiàn)在可以實(shí)現(xiàn)音頻的文件錄制和停止,并生成pcm文件,那么暫停時(shí)將這次文件先保存下來(lái),恢復(fù)播放后開(kāi)始新一輪的錄制,那么最后會(huì)生成多個(gè)pcm音頻,再將這些pcm文件進(jìn)行合并,這樣就實(shí)現(xiàn)了暫停/恢復(fù)的功能了。

    實(shí)現(xiàn)

    • 實(shí)現(xiàn)的重點(diǎn)在于如何控制錄音的狀態(tài)
    public class RecordHelper {private volatile RecordState state = RecordState.IDLE;private AudioRecordThread audioRecordThread;private File recordFile = null;private File tmpFile = null;private List<File> files = new ArrayList<>();public void start(String filePath, RecordConfig config) {this.currentConfig = config;if (state != RecordState.IDLE) {Logger.e(TAG, "狀態(tài)異常當(dāng)前狀態(tài): %s", state.name());return;}recordFile = new File(filePath);String tempFilePath = getTempFilePath();Logger.i(TAG, "tmpPCM File: %s", tempFilePath);tmpFile = new File(tempFilePath);audioRecordThread = new AudioRecordThread();audioRecordThread.start();}public void stop() {if (state == RecordState.IDLE) {Logger.e(TAG, "狀態(tài)異常當(dāng)前狀態(tài): %s", state.name());return;}//若在暫停中直接停止,則直接合并文件即可if (state == RecordState.PAUSE) {makeFile();state = RecordState.IDLE;} else {state = RecordState.STOP;}}public void pause() {if (state != RecordState.RECORDING) {Logger.e(TAG, "狀態(tài)異常當(dāng)前狀態(tài): %s", state.name());return;}state = RecordState.PAUSE;}public void resume() {if (state != RecordState.PAUSE) {Logger.e(TAG, "狀態(tài)異常當(dāng)前狀態(tài): %s", state.name());return;}String tempFilePath = getTempFilePath();Logger.i(TAG, "tmpPCM File: %s", tempFilePath);tmpFile = new File(tempFilePath);audioRecordThread = new AudioRecordThread();audioRecordThread.start();}private class AudioRecordThread extends Thread {private AudioRecord audioRecord;private int bufferSize;AudioRecordThread() {bufferSize = AudioRecord.getMinBufferSize(currentConfig.getFrequency(),currentConfig.getChannel(), currentConfig.getEncoding()) * RECORD_AUDIO_BUFFER_TIMES;audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, currentConfig.getFrequency(),currentConfig.getChannel(), currentConfig.getEncoding(), bufferSize);}@Overridepublic void run() {super.run();state = RecordState.RECORDING;notifyState();Logger.d(TAG, "開(kāi)始錄制");FileOutputStream fos = null;try {fos = new FileOutputStream(tmpFile);audioRecord.startRecording();byte[] byteBuffer = new byte[bufferSize];while (state == RecordState.RECORDING) {int end = audioRecord.read(byteBuffer, 0, byteBuffer.length);fos.write(byteBuffer, 0, end);fos.flush();}audioRecord.stop();//1. 將本次錄音的文件暫存下來(lái),用于合并files.add(tmpFile);//2. 再此判斷終止循環(huán)的狀態(tài)是暫停還是停止,并做相應(yīng)處理if (state == RecordState.STOP) {makeFile();} else {Logger.i(TAG, "暫停!");}} catch (Exception e) {Logger.e(e, TAG, e.getMessage());} finally {try {if (fos != null) {fos.close();}} catch (IOException e) {Logger.e(e, TAG, e.getMessage());}}if (state != RecordState.PAUSE) {state = RecordState.IDLE;notifyState();Logger.d(TAG, "錄音結(jié)束");}}}private void makeFile() {//合并文件boolean mergeSuccess = mergePcmFiles(recordFile, files);//TODO:轉(zhuǎn)換wavLogger.i(TAG, "錄音完成! path: %s ; 大小:%s", recordFile.getAbsoluteFile(), recordFile.length());}/*** 合并Pcm文件** @param recordFile 輸出文件* @param files 多個(gè)文件源* @return 是否成功*/private boolean mergePcmFiles(File recordFile, List<File> files) {if (recordFile == null || files == null || files.size() <= 0) {return false;}FileOutputStream fos = null;BufferedOutputStream outputStream = null;byte[] buffer = new byte[1024];try {fos = new FileOutputStream(recordFile);outputStream = new BufferedOutputStream(fos);for (int i = 0; i < files.size(); i++) {BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(files.get(i)));int readCount;while ((readCount = inputStream.read(buffer)) > 0) {outputStream.write(buffer, 0, readCount);}inputStream.close();}} catch (Exception e) {Logger.e(e, TAG, e.getMessage());return false;} finally {try {if (fos != null) {fos.close();}if (outputStream != null) {outputStream.close();}} catch (IOException e) {e.printStackTrace();}}//3. 合并后記得刪除緩存文件并清除listfor (int i = 0; i < files.size(); i++) {files.get(i).delete();}files.clear();return true;}}

    其他

    在此后如若需要添加錄音狀態(tài)回調(diào),記得使用Handler做好線(xiàn)程切換。

    4. PCM轉(zhuǎn)WAV格式音頻

    前面幾部分已經(jīng)介紹了PCM音頻文件的錄制,這一部分主要介紹下pcm轉(zhuǎn)wav。

    wav 和 pcm

    一般通過(guò)麥克風(fēng)采集的錄音數(shù)據(jù)都是PCM格式的,即不包含頭部信息,播放器無(wú)法知道音頻采樣率、位寬等參數(shù),導(dǎo)致無(wú)法播放,顯然是非常不方便的。pcm轉(zhuǎn)換成wav,我們只需要在pcm的文件起始位置加上至少44個(gè)字節(jié)的WAV頭信息即可。

    RIFF

    • WAVE文件是以RIFF(Resource Interchange File Format, “資源交互文件格式”)格式來(lái)組織內(nèi)部結(jié)構(gòu)的。
      RIFF文件結(jié)構(gòu)可以看作是樹(shù)狀結(jié)構(gòu),其基本構(gòu)成是稱(chēng)為"塊"(Chunk)的單元.
    • WAVE文件是由若干個(gè)Chunk組成的。按照在文件中的出現(xiàn)位置包括:RIFF WAVE Chunk, Format Chunk, Fact Chunk(可選), Data Chunk。
    Fact Chunk 在壓縮后或在非PCM編碼時(shí)存在

    WAV頭文件

    所有的WAV都有一個(gè)文件頭,這個(gè)文件頭記錄著音頻流的編碼參數(shù)。數(shù)據(jù)塊的記錄方式是little-endian字節(jié)順序。

    偏移地址命名內(nèi)容
    00-03ChunkId“RIFF”
    04-07ChunkSize下個(gè)地址開(kāi)始到文件尾的總字節(jié)數(shù)(此Chunk的數(shù)據(jù)大小)
    08-11fccType“WAVE”
    12-15SubChunkId1"fmt ",最后一位空格。
    16-19SubChunkSize1一般為16,表示fmt Chunk的數(shù)據(jù)塊大小為16字節(jié),即20-35
    20-21FormatTag1:表示是PCM 編碼
    22-23Channels聲道數(shù),單聲道為1,雙聲道為2
    24-27SamplesPerSec采樣率
    28-31BytesPerSec碼率 :采樣率 * 采樣位數(shù) * 聲道個(gè)數(shù),bytePerSecond = sampleRate * (bitsPerSample / 8) * channels
    32-33BlockAlign每次采樣的大小:位寬*聲道數(shù)/8
    34-35BitsPerSample位寬
    36-39SubChunkId2“data”
    40-43SubChunkSize2音頻數(shù)據(jù)的長(zhǎng)度
    44-…data音頻數(shù)據(jù)

    java 生成頭文件

    WavHeader.class

    public static class WavHeader {/*** RIFF數(shù)據(jù)塊*/final String riffChunkId = "RIFF";int riffChunkSize;final String riffType = "WAVE";/*** FORMAT 數(shù)據(jù)塊*/final String formatChunkId = "fmt ";final int formatChunkSize = 16;final short audioFormat = 1;short channels;int sampleRate;int byteRate;short blockAlign;short sampleBits;/*** FORMAT 數(shù)據(jù)塊*/final String dataChunkId = "data";int dataChunkSize;WavHeader(int totalAudioLen, int sampleRate, short channels, short sampleBits) {this.riffChunkSize = totalAudioLen;this.channels = channels;this.sampleRate = sampleRate;this.byteRate = sampleRate * sampleBits / 8 * channels;this.blockAlign = (short) (channels * sampleBits / 8);this.sampleBits = sampleBits;this.dataChunkSize = totalAudioLen - 44;}public byte[] getHeader() {byte[] result;result = ByteUtils.merger(ByteUtils.toBytes(riffChunkId), ByteUtils.toBytes(riffChunkSize));result = ByteUtils.merger(result, ByteUtils.toBytes(riffType));result = ByteUtils.merger(result, ByteUtils.toBytes(formatChunkId));result = ByteUtils.merger(result, ByteUtils.toBytes(formatChunkSize));result = ByteUtils.merger(result, ByteUtils.toBytes(audioFormat));result = ByteUtils.merger(result, ByteUtils.toBytes(channels));result = ByteUtils.merger(result, ByteUtils.toBytes(sampleRate));result = ByteUtils.merger(result, ByteUtils.toBytes(byteRate));result = ByteUtils.merger(result, ByteUtils.toBytes(blockAlign));result = ByteUtils.merger(result, ByteUtils.toBytes(sampleBits));result = ByteUtils.merger(result, ByteUtils.toBytes(dataChunkId));result = ByteUtils.merger(result, ByteUtils.toBytes(dataChunkSize));return result;} }

    ByteUtils: https://github.com/zhaolewei/ZlwAudioRecorder/blob/master/recorderlib/src/main/java/com/zlw/main/recorderlib/utils/ByteUtils.java

    PCM轉(zhuǎn)Wav

    WavUtils.java

    public class WavUtils {private static final String TAG = WavUtils.class.getSimpleName();/*** 生成wav格式的Header* wave是RIFF文件結(jié)構(gòu),每一部分為一個(gè)chunk,其中有RIFF WAVE chunk,* FMT Chunk,Fact chunk(可選),Data chunk** @param totalAudioLen 不包括header的音頻數(shù)據(jù)總長(zhǎng)度* @param sampleRate 采樣率,也就是錄制時(shí)使用的頻率* @param channels audioRecord的頻道數(shù)量* @param sampleBits 位寬*/public static byte[] generateWavFileHeader(int totalAudioLen, int sampleRate, int channels, int sampleBits) {WavHeader wavHeader = new WavHeader(totalAudioLen, sampleRate, (short) channels, (short) sampleBits);return wavHeader.getHeader();}}/*** 將header寫(xiě)入到pcm文件中 不修改文件名** @param file 寫(xiě)入的pcm文件* @param header wav頭數(shù)據(jù)*/public static void writeHeader(File file, byte[] header) {if (!FileUtils.isFile(file)) {return;}RandomAccessFile wavRaf = null;try {wavRaf = new RandomAccessFile(file, "rw");wavRaf.seek(0);wavRaf.write(header);wavRaf.close();} catch (Exception e) {Logger.e(e, TAG, e.getMessage());} finally {try {if (wavRaf != null) {wavRaf.close();}} catch (IOException e) {Logger.e(e, TAG, e.getMessage());}}

    RecordHelper.java

    private void makeFile() {mergePcmFiles(recordFile, files);//這里實(shí)現(xiàn)上一篇未完成的工作byte[] header = WavUtils.generateWavFileHeader((int) resultFile.length(), currentConfig.getSampleRate(), currentConfig.getChannelCount(), currentConfig.getEncoding());WavUtils.writeHeader(resultFile, header);Logger.i(TAG, "錄音完成! path: %s ; 大小:%s", recordFile.getAbsoluteFile(), recordFile.length());}

    參考鏈接:

    http://soundfile.sapp.org/doc/WaveFormat/

    5. Mp3的錄制 - 編譯Lame源碼

    編譯 so包

    1.下載lame

    官網(wǎng)(科學(xué)上網(wǎng)): http://lame.sourceforge.net/download.php
    lame-3.100:https://pan.baidu.com/s/1U77GAq1nn3bVXFMEhRyo8g

    2.使用ndk-build編譯源碼

    2.1 在任意位置創(chuàng)建如下的目錄結(jié)構(gòu):

    文件夾名稱(chēng)隨意,與.mk 文件中路徑一致即可

    2.2 解壓下載好的lame源碼
    解壓后將其/lame-3.100/libmp3lame/目錄中.c和.h文件和/lame-3.100//include/中的 lame.h拷貝到/jni/lame-3.100_libmp3lame中

    3.100版本 有42個(gè)文件

    2.3 修改部分文件

  • 刪除fft.c文件的47行的#include "vector/lame_intrin.h"
  • 刪除set_get.h文件的24行的#include <lame.h>
  • 將util.h文件的570行的extern ieee754_float32_t fast_log2(ieee754_float32_t x); 替換為 extern float fast_log2(float x);
  • 2.4 編寫(xiě)Mp3Encoder.c和Mp3Encoder.h對(duì)接java代碼

    2.4.1 Mp3Encoder.c

    注意修改包名 #include "lame-3.100_libmp3lame/lame.h" #include "Mp3Encoder.h"static lame_global_flags *glf = NULL; //TODO這里包名要與java中對(duì)接文件的路徑一致(這里是路徑是com.zlw.main.recorderlib.recorder.mp3,java文件: Mp3Encoder.java),下同 JNIEXPORT void JNICALL Java_com_zlw_main_recorderlib_recorder_mp3_Mp3Encoder_init(JNIEnv *env, jclass cls, jint inSamplerate, jint outChannel,jint outSamplerate, jint outBitrate, jint quality) {if (glf != NULL) {lame_close(glf);glf = NULL;}glf = lame_init();lame_set_in_samplerate(glf, inSamplerate);lame_set_num_channels(glf, outChannel);lame_set_out_samplerate(glf, outSamplerate);lame_set_brate(glf, outBitrate);lame_set_quality(glf, quality);lame_init_params(glf); }JNIEXPORT jint JNICALL Java_com_zlw_main_recorderlib_recorder_mp3_Mp3Encoder_encode(JNIEnv *env, jclass cls, jshortArray buffer_l, jshortArray buffer_r,jint samples, jbyteArray mp3buf) {jshort* j_buffer_l = (*env)->GetShortArrayElements(env, buffer_l, NULL);jshort* j_buffer_r = (*env)->GetShortArrayElements(env, buffer_r, NULL);const jsize mp3buf_size = (*env)->GetArrayLength(env, mp3buf);jbyte* j_mp3buf = (*env)->GetByteArrayElements(env, mp3buf, NULL);int result = lame_encode_buffer(glf, j_buffer_l, j_buffer_r,samples, j_mp3buf, mp3buf_size);(*env)->ReleaseShortArrayElements(env, buffer_l, j_buffer_l, 0);(*env)->ReleaseShortArrayElements(env, buffer_r, j_buffer_r, 0);(*env)->ReleaseByteArrayElements(env, mp3buf, j_mp3buf, 0);return result; }JNIEXPORT jint JNICALL Java_com_zlw_main_recorderlib_recorder_mp3_Mp3Encoder_flush(JNIEnv *env, jclass cls, jbyteArray mp3buf) {const jsize mp3buf_size = (*env)->GetArrayLength(env, mp3buf);jbyte* j_mp3buf = (*env)->GetByteArrayElements(env, mp3buf, NULL);int result = lame_encode_flush(glf, j_mp3buf, mp3buf_size);(*env)->ReleaseByteArrayElements(env, mp3buf, j_mp3buf, 0);return result; }JNIEXPORT void JNICALL Java_com_zlw_main_recorderlib_recorder_mp3_Mp3Encoder_close(JNIEnv *env, jclass cls) {lame_close(glf);glf = NULL; }

    2.4.2 Mp3Encoder.h

    注意修改包名 /* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h>#ifndef _Included_Mp3Encoder #define _Included_Mp3Encoder #ifdef __cplusplus extern "C" { #endif /** Class: com.zlw.main.recorderlib.recorder.mp3.Mp3Encoder* Method: init*/ JNIEXPORT void JNICALL Java_com_zlw_main_recorderlib_recorder_mp3_Mp3Encoder_init(JNIEnv *, jclass, jint, jint, jint, jint, jint);JNIEXPORT jint JNICALL Java_com_zlw_main_recorderlib_recorder_mp3_Mp3Encoder_encode(JNIEnv *, jclass, jshortArray, jshortArray, jint, jbyteArray);JNIEXPORT jint JNICALL Java_com_zlw_main_recorderlib_recorder_mp3_Mp3Encoder_flush(JNIEnv *, jclass, jbyteArray);JNIEXPORT void JNICALL Java_com_zlw_main_recorderlib_recorder_mp3_Mp3Encoder_close(JNIEnv *, jclass);#ifdef __cplusplus } #endif #endif

    2.5 編寫(xiě)Android.mk 和Application.mk

    路徑與創(chuàng)建的目錄應(yīng)當(dāng)一致

    2.5.1 Android.mk

    LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LAME_LIBMP3_DIR := lame-3.100_libmp3lameLOCAL_MODULE := mp3lameLOCAL_SRC_FILES :=\ $(LAME_LIBMP3_DIR)/bitstream.c \ $(LAME_LIBMP3_DIR)/fft.c \ $(LAME_LIBMP3_DIR)/id3tag.c \ $(LAME_LIBMP3_DIR)/mpglib_interface.c \ $(LAME_LIBMP3_DIR)/presets.c \ $(LAME_LIBMP3_DIR)/quantize.c \ $(LAME_LIBMP3_DIR)/reservoir.c \ $(LAME_LIBMP3_DIR)/tables.c \ $(LAME_LIBMP3_DIR)/util.c \ $(LAME_LIBMP3_DIR)/VbrTag.c \ $(LAME_LIBMP3_DIR)/encoder.c \ $(LAME_LIBMP3_DIR)/gain_analysis.c \ $(LAME_LIBMP3_DIR)/lame.c \ $(LAME_LIBMP3_DIR)/newmdct.c \ $(LAME_LIBMP3_DIR)/psymodel.c \ $(LAME_LIBMP3_DIR)/quantize_pvt.c \ $(LAME_LIBMP3_DIR)/set_get.c \ $(LAME_LIBMP3_DIR)/takehiro.c \ $(LAME_LIBMP3_DIR)/vbrquantize.c \ $(LAME_LIBMP3_DIR)/version.c \ MP3Encoder.cinclude $(BUILD_SHARED_LIBRARY)

    2.5.2 Application.mk

    若只需要編譯armeabi的so包可將其他刪除 APP_ABI := armeabi armeabi-v7a arm64-v8a x86 x86_64 mips mips64 APP_MODULES := mp3lame APP_CFLAGS += -DSTDC_HEADERS APP_PLATFORM := android-21

    編譯

    到達(dá)這一步,所有的文件都已經(jīng)準(zhǔn)備好了
    在命令行中切換到j(luò)ni目錄中,執(zhí)行ndk-build開(kāi)始編譯

    如果不能識(shí)別ndk-build命令 需要配置下環(huán)境變量

    6. Mp3的錄制 - 使用Lame實(shí)時(shí)錄制MP3格式音頻

    前言

    上一篇介紹了如何去編譯so文件,這一篇主要介紹下如何實(shí)時(shí)將pcm數(shù)據(jù)轉(zhuǎn)換為MP3數(shù)據(jù)。

    實(shí)現(xiàn)過(guò)程:
    AudioRecorder在開(kāi)啟錄音后,通過(guò)read方法不斷獲取pcm的采樣數(shù)據(jù),每次獲取到數(shù)據(jù)后交給lame去處理,處理完成后存入文件中。

    這一篇相對(duì)之前代碼,增加了兩個(gè)類(lèi):Mp3Encoder.java 和 Mp3EncoderThread.java

    • Mp3Encoder: 通過(guò)Jni調(diào)用so文件的c代碼,將pcm轉(zhuǎn)換成mp3格式數(shù)據(jù)
    • Mp3EncodeThread: 將pcm轉(zhuǎn)換成mp3時(shí)需要開(kāi)啟子線(xiàn)程進(jìn)行統(tǒng)一管理,以及全部轉(zhuǎn)碼完成的回調(diào)

    代碼實(shí)現(xiàn)

    Mp3Encoder.java

    public class Mp3Encoder {static {System.loadLibrary("mp3lame");}public native static void close();public native static int encode(short[] buffer_l, short[] buffer_r, int samples, byte[] mp3buf);public native static int flush(byte[] mp3buf);public native static void init(int inSampleRate, int outChannel, int outSampleRate, int outBitrate, int quality);public static void init(int inSampleRate, int outChannel, int outSampleRate, int outBitrate) {init(inSampleRate, outChannel, outSampleRate, outBitrate, 7);} }

    Mp3EncodeThread.java

    每次有新的pcm數(shù)據(jù)后將數(shù)據(jù)打包成ChangeBuffer 類(lèi)型,通過(guò)addChangeBuffer()存放到線(xiàn)程隊(duì)列當(dāng)中,線(xiàn)程開(kāi)啟后會(huì)不斷輪詢(xún)隊(duì)列內(nèi)容,當(dāng)有內(nèi)容后開(kāi)始轉(zhuǎn)碼,無(wú)內(nèi)容時(shí)進(jìn)入阻塞,直到數(shù)據(jù)全部處理完成后,關(guān)閉輪詢(xún)。

    public class Mp3EncodeThread extends Thread {private static final String TAG = Mp3EncodeThread.class.getSimpleName();/*** mp3文件的碼率 32kbit/s = 4kb/s*/private static final int OUT_BITRATE = 32;private List<ChangeBuffer> cacheBufferList = Collections.synchronizedList(new LinkedList<ChangeBuffer>());private File file;private FileOutputStream os;private byte[] mp3Buffer;private EncordFinishListener encordFinishListener;/*** 是否已停止錄音*/private volatile boolean isOver = false;/*** 是否繼續(xù)輪詢(xún)數(shù)據(jù)隊(duì)列*/private volatile boolean start = true;public Mp3EncodeThread(File file, int bufferSize) {this.file = file;mp3Buffer = new byte[(int) (7200 + (bufferSize * 2 * 1.25))];RecordConfig currentConfig = RecordService.getCurrentConfig();int sampleRate = currentConfig.getSampleRate();Mp3Encoder.init(sampleRate, currentConfig.getChannelCount(), sampleRate, OUT_BITRATE);}@Overridepublic void run() {try {this.os = new FileOutputStream(file);} catch (FileNotFoundException e) {Logger.e(e, TAG, e.getMessage());return;}while (start) {ChangeBuffer next = next();Logger.v(TAG, "處理數(shù)據(jù):%s", next == null ? "null" : next.getReadSize());lameData(next);}}public void addChangeBuffer(ChangeBuffer changeBuffer) {if (changeBuffer != null) {cacheBufferList.add(changeBuffer);synchronized (this) {notify();}}}public void stopSafe(EncordFinishListener encordFinishListener) {this.encordFinishListener = encordFinishListener;isOver = true;synchronized (this) {notify();}}private ChangeBuffer next() {for (; ; ) {if (cacheBufferList == null || cacheBufferList.size() == 0) {try {if (isOver) {finish();}synchronized (this) {wait();}} catch (Exception e) {Logger.e(e, TAG, e.getMessage());}} else {return cacheBufferList.remove(0);}}}private void lameData(ChangeBuffer changeBuffer) {if (changeBuffer == null) {return;}short[] buffer = changeBuffer.getData();int readSize = changeBuffer.getReadSize();if (readSize > 0) {int encodedSize = Mp3Encoder.encode(buffer, buffer, readSize, mp3Buffer);if (encodedSize < 0) {Logger.e(TAG, "Lame encoded size: " + encodedSize);}try {os.write(mp3Buffer, 0, encodedSize);} catch (IOException e) {Logger.e(e, TAG, "Unable to write to file");}}}private void finish() {start = false;final int flushResult = Mp3Encoder.flush(mp3Buffer);if (flushResult > 0) {try {os.write(mp3Buffer, 0, flushResult);os.close();} catch (final IOException e) {Logger.e(TAG, e.getMessage());}}Logger.d(TAG, "轉(zhuǎn)換結(jié)束 :%s", file.length());if (encordFinishListener != null) {encordFinishListener.onFinish();}}public static class ChangeBuffer {private short[] rawData;private int readSize;public ChangeBuffer(short[] rawData, int readSize) {this.rawData = rawData.clone();this.readSize = readSize;}short[] getData() {return rawData;}int getReadSize() {return readSize;}}public interface EncordFinishListener {/*** 格式轉(zhuǎn)換完畢*/void onFinish();} }

    使用

    private class AudioRecordThread extends Thread {private AudioRecord audioRecord;private int bufferSize;AudioRecordThread() {bufferSize = AudioRecord.getMinBufferSize(currentConfig.getSampleRate(),currentConfig.getChannelConfig(), currentConfig.getEncodingConfig()) * RECORD_AUDIO_BUFFER_TIMES;audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, currentConfig.getSampleRate(),currentConfig.getChannelConfig(), currentConfig.getEncodingConfig(), bufferSize);if (currentConfig.getFormat() == RecordConfig.RecordFormat.MP3 && mp3EncodeThread == null) {initMp3EncoderThread(bufferSize);}}@Overridepublic void run() {super.run();startMp3Recorder();}private void initMp3EncoderThread(int bufferSize) {try {mp3EncodeThread = new Mp3EncodeThread(resultFile, bufferSize);mp3EncodeThread.start();} catch (Exception e) {Logger.e(e, TAG, e.getMessage());}}private void startMp3Recorder() {state = RecordState.RECORDING;notifyState();try {audioRecord.startRecording();short[] byteBuffer = new short[bufferSize];while (state == RecordState.RECORDING) {int end = audioRecord.read(byteBuffer, 0, byteBuffer.length);if (mp3EncodeThread != null) {mp3EncodeThread.addChangeBuffer(new Mp3EncodeThread.ChangeBuffer(byteBuffer, end));}notifyData(ByteUtils.toBytes(byteBuffer));}audioRecord.stop();} catch (Exception e) {Logger.e(e, TAG, e.getMessage());notifyError("錄音失敗");}if (state != RecordState.PAUSE) {state = RecordState.IDLE;notifyState();if (mp3EncodeThread != null) {mp3EncodeThread.stopSafe(new Mp3EncodeThread.EncordFinishListener() {@Overridepublic void onFinish() {notifyFinish();}});} else {notifyFinish();}} else {Logger.d(TAG, "暫停");}}} }

    7. 音樂(lè)可視化-FFT頻譜圖

    項(xiàng)目地址:https://github.com/zhaolewei/MusicVisualizer
    視頻演示地址:https://www.bilibili.com/video/av30388154/

    實(shí)現(xiàn)

    實(shí)現(xiàn)流程:

    • 使用MediaPlayer播放傳入的音樂(lè),并拿到mediaPlayerId
    • 使用Visualizer類(lèi)拿到拿到MediaPlayer播放中的音頻數(shù)據(jù)(wave/fft)
    • 將數(shù)據(jù)用自定義控件展現(xiàn)出來(lái)

    準(zhǔn)備工作

    使用Visualizer需要錄音的動(dòng)態(tài)權(quán)限, 如果播放sd卡音頻需要STORAGE權(quán)限。

    private static final String[] PERMISSIONS = new String[]{Manifest.permission.RECORD_AUDIO,Manifest.permission.MODIFY_AUDIO_SETTINGS};ActivityCompat.requestPermissions(MainActivity.this, PERMISSIONS, 1); <uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    開(kāi)始播放

    private MediaPlayer.OnPreparedListener preparedListener = new /*** 播放音頻** @param raw 資源文件id*/private void doPlay(final int raw) {try {mediaPlayer = MediaPlayer.create(MyApp.getInstance(), raw);if (mediaPlayer == null) {Logger.e(TAG, "mediaPlayer is null");return;}mediaPlayer.setOnErrorListener(errorListener);mediaPlayer.setOnPreparedListener(preparedListener);} catch (Exception e) {Logger.e(e, TAG, e.getMessage());}}/*** 獲取MediaPlayerId* 可視化類(lèi)Visualizer需要此參數(shù)* @return MediaPlayerId*/public int getMediaPlayerId() {return mediaPlayer.getAudioSessionId();}

    使用可視化類(lèi)Visualizer獲取當(dāng)前音頻數(shù)據(jù)

    Visualizer 有兩個(gè)比較重要的參數(shù)

    • 設(shè)置可視化數(shù)據(jù)的數(shù)據(jù)大小 范圍[Visualizer.getCaptureSizeRange()[0]~Visualizer.getCaptureSizeRange()[1]]
    • 設(shè)置可視化數(shù)據(jù)的采集頻率 范圍[0~Visualizer.getMaxCaptureRate()]

    OnDataCaptureListener 有2個(gè)回調(diào),一個(gè)用于顯示FFT數(shù)據(jù),展示不同頻率的振幅,另一個(gè)用于顯示聲音的波形圖。

    private Visualizer.OnDataCaptureListener dataCaptureListener = new Visualizer.OnDataCaptureListener() {@Overridepublic void onWaveFormDataCapture(Visualizer visualizer, final byte[] waveform, int samplingRate) {audioView.post(new Runnable() {@Overridepublic void run() {audioView.setWaveData(waveform);}});}@Overridepublic void onFftDataCapture(Visualizer visualizer, final byte[] fft, int samplingRate) {audioView2.post(new Runnable() {@Overridepublic void run() {audioView2.setWaveData(fft);}});}};private void initVisualizer() {try {int mediaPlayerId = mediaPlayer.getMediaPlayerId();if (visualizer != null) {visualizer.release();}visualizer = new Visualizer(mediaPlayerId);/***可視化數(shù)據(jù)的大小: getCaptureSizeRange()[0]為最小值,getCaptureSizeRange()[1]為最大值*/int captureSize = Visualizer.getCaptureSizeRange()[1];int captureRate = Visualizer.getMaxCaptureRate() * 3 / 4;visualizer.setCaptureSize(captureSize);visualizer.setDataCaptureListener(dataCaptureListener, captureRate, true, true);visualizer.setScalingMode(Visualizer.SCALING_MODE_NORMALIZED);visualizer.setEnabled(true);} catch (Exception e) {Logger.e(TAG, "請(qǐng)檢查錄音權(quán)限");} }

    波形數(shù)據(jù)和傅里葉數(shù)據(jù)的關(guān)系如圖:

    快速傅里葉轉(zhuǎn)換(FFT)詳細(xì)分析: https://zhuanlan.zhihu.com/p/19763358

    編寫(xiě)自定義控件,展示數(shù)據(jù)

    1.處理數(shù)據(jù): visualizer 回調(diào)中的數(shù)據(jù)中是存在負(fù)數(shù)的,需要轉(zhuǎn)換一下,用于顯示

    當(dāng)byte-128時(shí)Math.abs(fft[i]) 計(jì)算出來(lái)的值會(huì)越界,需要手動(dòng)處理一下 byte 的范圍: -128~127 /*** 預(yù)處理數(shù)據(jù)** @return*/private static byte[] readyData(byte[] fft) {byte[] newData = new byte[LUMP_COUNT];byte abs;for (int i = 0; i < LUMP_COUNT; i++) {abs = (byte) Math.abs(fft[i]);//描述:Math.abs -128時(shí)越界newData[i] = abs < 0 ? 127 : abs;}return newData;}

    2. 緊接著就是根據(jù)數(shù)據(jù)去繪制圖形

    @Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);wavePath.reset();for (int i = 0; i < LUMP_COUNT; i++) {if (waveData == null) {canvas.drawRect((LUMP_WIDTH + LUMP_SPACE) * i,LUMP_MAX_HEIGHT - LUMP_MIN_HEIGHT,(LUMP_WIDTH + LUMP_SPACE) * i + LUMP_WIDTH,LUMP_MAX_HEIGHT,lumpPaint);continue;}switch (upShowStyle) {case STYLE_HOLLOW_LUMP:drawLump(canvas, i, false);break;case STYLE_WAVE:drawWave(canvas, i, false);break;default:break;}switch (downShowStyle) {case STYLE_HOLLOW_LUMP:drawLump(canvas, i, true);break;case STYLE_WAVE:drawWave(canvas, i, true);break;default:break;}}}/*** 繪制矩形條*/private void drawLump(Canvas canvas, int i, boolean reversal) {int minus = reversal ? -1 : 1;if (waveData[i] < 0) {Logger.w("waveData", "waveData[i] < 0 data: %s", waveData[i]);}float top = (LUMP_MAX_HEIGHT - (LUMP_MIN_HEIGHT + waveData[i] * SCALE) * minus);canvas.drawRect(LUMP_SIZE * i,top,LUMP_SIZE * i + LUMP_WIDTH,LUMP_MAX_HEIGHT,lumpPaint);}/*** 繪制曲線(xiàn)* 這里使用貝塞爾曲線(xiàn)來(lái)繪制*/private void drawWave(Canvas canvas, int i, boolean reversal) {if (pointList == null || pointList.size() < 2) {return;}float ratio = SCALE * (reversal ? -1 : 1);if (i < pointList.size() - 2) {Point point = pointList.get(i);Point nextPoint = pointList.get(i + 1);int midX = (point.x + nextPoint.x) >> 1;if (i == 0) {wavePath.moveTo(point.x, LUMP_MAX_HEIGHT - point.y * ratio);}wavePath.cubicTo(midX, LUMP_MAX_HEIGHT - point.y * ratio,midX, LUMP_MAX_HEIGHT - nextPoint.y * ratio,nextPoint.x, LUMP_MAX_HEIGHT - nextPoint.y * ratio);canvas.drawPath(wavePath, lumpPaint);}}

    總結(jié)

    以上是生活随笔為你收集整理的Android音频开发的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

    亚洲一区精品二人人爽久久 | 在线观看中文字幕一区 | 国产一区二区精品91 | 国产精品视频99 | 色视频在线观看 | www.天天色.com| 久久国产一二区 | 97韩国电影 | 亚洲最新精品 | 国产精品专区在线观看 | 看黄色.com| 四虎在线免费 | 日韩在线观看av | 91色在线观看 | www.色婷婷.com| av+在线播放在线播放 | a午夜电影 | 久久手机精品视频 | 欧美久草在线 | 亚洲国产精品va在线看黑人动漫 | 精油按摩av | av在线精品| 黄色a一级视频 | 天天操一操 | 久久天天综合网 | 欧美色图狠狠干 | 国产淫片免费看 | 亚洲精品一区二区三区在线观看 | 欧美无极色 | 最新av电影网站 | 国产精品免费一区二区 | 日本性生活免费看 | 六月丁香综合网 | 1024久久| 国产成人亚洲在线观看 | 一区精品在线 | 欧美一区二区在线 | 国产九九热视频 | a视频免费 | 黄污视频网站 | 日韩a在线观看 | 香蕉视频国产在线观看 | 国产色视频网站 | 国产亚洲综合精品 | 久久精品综合一区 | 天天操天天艹 | 免费一级毛毛片 | 在线观看久 | 日韩资源在线 | av电影免费在线播放 | 日韩精品一区二区在线观看 | 中文字幕在线免费观看 | 91cn国产在线| 国产精品第52页 | 久久精品视频2 | 麻豆 free xxxx movies hd | 手机av资源| 亚洲专区欧美 | 狠狠躁夜夜av | 亚洲传媒在线 | 在线色亚洲| 日韩高清不卡一区二区三区 | 亚洲日b视频 | 欧美极品少妇xxxxⅹ欧美极品少妇xxxx亚洲精品 | 亚洲天堂精品 | 亚洲欧美日韩在线看 | 99久高清在线观看视频99精品热在线观看视频 | 久久久久亚洲精品男人的天堂 | 欧美精品免费一区二区 | 狠狠干五月天 | 精品国产乱码久久久久久三级人 | 久久人人爽爽 | 欧美日韩国产精品一区二区三区 | 日韩欧美一区二区三区视频 | 亚洲欧美色婷婷 | 国产黄色特级片 | 97高清免费视频 | 日本aa在线 | 国产精品久久久久永久免费看 | 精品视频123区在线观看 | 中文字幕高清在线播放 | 婷婷丁香花五月天 | 丝袜制服综合网 | 日韩 在线 | 色天天天 | 国产精品久久久久免费 | 日日夜夜综合网 | 视频在线99re | 黄色片网站av | 日韩免费在线观看视频 | 在线视频91 | 激情欧美一区二区免费视频 | aav在线 | 人人超碰免费 | 天天综合天天做天天综合 | 中文字幕免费播放 | 黄色福利网站 | 国产成人在线看 | 人人草人 | 国产馆在线播放 | 日日干美女 | 欧美福利网站 | 国产原创91| 国产成人av免费在线观看 | 91精品久久久久久久91蜜桃 | 中文字幕在线免费97 | 国产精品美女 | 日韩在线视频观看 | 久久人人爽 | 91大神电影| 欧美日韩在线播放 | 久99视频| 欧美极品xxxx | 夜夜摸夜夜爽 | 久久伊人爱 | 中文字幕乱码电影 | adn—256中文在线观看 | 黄色三级网站在线观看 | 久草精品资源 | 久久久精品国产免费观看同学 | 成年免费在线视频 | 99热在线精品观看 | 国产亚州av| 亚洲少妇自拍 | 久久这里只有精品视频首页 | 国产九九精品视频 | 国产亚洲精品久久久网站好莱 | 国产99久久久国产精品 | 国产精品免费久久久久久 | 成人一区二区在线 | 天天干天天操天天爱 | 欧美精品在线视频 | 亚洲天堂香蕉 | 欧美精品资源 | 日韩免费| 亚洲精品字幕 | 欧美一区在线观看视频 | 97免费在线观看视频 | 丁香高清视频在线看看 | 区一区二区三在线观看 | 国产一区二区三区免费在线观看 | 婷婷精品在线 | 欧美一级视频一区 | 欧美aaa大片| 蜜臀久久99精品久久久久久网站 | 欧美日韩一区二区在线 | 日本一区二区不卡高清 | 久久久久久综合网天天 | 日韩高清免费在线 | 极品久久久久久久 | 狂野欧美激情性xxxx | 欧美激情综合网 | 在线免费观看视频一区 | 日本久久久久久久久久久 | 99久久久久久久 | 国产精品一区二区在线看 | 久久人人爽人人人人片 | 日韩字幕| 久久久久成人精品免费播放动漫 | 五月激情丁香图片 | 国产精品1000 | 麻豆视频在线看 | 国产一级在线看 | 国产免费资源 | 国产高清一区二区 | 一级免费av| 又黄又刺激视频 | 97色se | 成人综合婷婷国产精品久久免费 | 天天干天天摸 | 中文av在线免费观看 | 久久蜜臀一区二区三区av | 精品福利片 | 五月综合网 | 色是在线视频 | 996久久国产精品线观看 | 99这里精品| 免费看一级特黄a大片 | 久久欧美视频 | 国产亚洲精品日韩在线tv黄 | 国产一区自拍视频 | 人人澡人人添人人爽一区二区 | 91亚洲精品久久久蜜桃网站 | 久久成人资源 | 日韩超碰 | 久久久久久久久久久福利 | 亚洲精品黄色在线观看 | 51久久成人国产精品麻豆 | 久久影视中文字幕 | 亚洲精品白浆高清久久久久久 | 999免费视频 | 欧美另类xxxxx | 色综合婷婷久久 | 国产精品18久久久久久久 | 欧美一级免费在线 | 天天操综合 | 国产麻豆果冻传媒在线观看 | 亚洲另类视频在线观看 | 国产高清视频 | 91香蕉视频色版 | 日韩精品一二三 | 婷婷在线播放 | 久久免费美女视频 | 日韩理论片中文字幕 | 日韩视频在线一区 | 丁香婷婷综合激情五月色 | 中文字幕综合在线 | 天堂av免费观看 | 午夜婷婷在线观看 | 国产精品二区在线观看 | 国产在线欧美 | 久久免费的视频 | 国产成人久久精品77777 | 婷婷激情网站 | 亚洲精品播放 | 久久久黄视频 | 欧美一区中文字幕 | 久久看片网站 | 精品国产一区二区三区久久影院 | 国产99久久久国产精品成人免费 | 日韩在线观看的 | 在线观看岛国片 | 狠狠狠色丁香综合久久天下网 | 午夜黄色一级片 | 91精品国产自产在线观看永久 | 亚洲精品午夜视频 | 久久伊人免费视频 | 中文字幕 在线看 | 91视频成人免费 | 91精品视频免费看 | 欧洲精品久久久久毛片完整版 | 久草免费色站 | 热久久国产精品 | 精品一二三四视频 | 91av资源在线| 日韩aa视频| 日韩成人免费在线观看 | 成人三级av| 久久99久久99精品免视看婷婷 | 国产成人免费高清 | 亚洲精选在线 | 亚洲黄色av一区 | 激情喷水 | 天堂av免费在线 | 国产成人综合在线观看 | 欧美激情第八页 | 久久国产91 | 久久久精品国产一区二区三区 | 人人躁| av片子在线观看 | 精品福利国产 | 久久精品网站视频 | 色激情五月 | 久久国产福利 | 欧美 亚洲 另类 激情 另类 | 国产在线一区二区三区播放 | 精品自拍av | www.亚洲激情.com | 欧美在线一二 | 麻豆精品视频在线 | 黄色特级毛片 | 国产精品久久久久久久久久了 | 久草久草在线 | 在线看国产一区 | 婷婷久草 | 免费看搞黄视频网站 | 狠狠插天天干 | 日韩av电影手机在线观看 | 日韩欧美视频在线免费观看 | 天天弄天天干 | 欧美va天堂va视频va在线 | 精品免费在线视频 | 日韩网站中文字幕 | 国产色一区 | 国产精品露脸在线 | 国产精品一区二区久久精品爱涩 | 亚洲成人高清在线 | 国产成人免费网站 | 黄色视屏在线免费观看 | 黄色三级网站 | 四虎在线观看视频 | 黄色大片入口 | 在线观看视频国产一区 | 国产免费成人av | 日韩3区 | 亚洲美女免费精品视频在线观看 | 免费的黄色的网站 | 国产粉嫩在线 | 在线99视频 | 天天射网 | 久久国产精品99久久久久 | 九九色网| 国产青春久久久国产毛片 | 亚洲高清激情 | 中文区中文字幕免费看 | 欧美热久久 | 国产美女网站在线观看 | 免费国产在线精品 | 九九热在线精品 | 久久视频这里有久久精品视频11 | 国产69精品久久久久久久久久 | 亚洲一级黄色大片 | 久久精品爱爱视频 | 国产精品嫩草55av | 中文字幕电影网 | 五月激情片 | 日韩字幕在线观看 | 日韩国产精品久久 | 激情久久小说 | 91在线中文 | 99精品国产一区二区三区不卡 | 在线观看 国产 | 欧美激情视频一区 | 日本精品视频网站 | 婷婷在线视频 | 在线视频专区 | 五月天免费网站 | av片子在线观看 | 日本中文字幕高清 | 五月天久久婷 | 亚洲国产日韩精品 | 正在播放国产精品 | 五月天激情电影 | 亚洲精选视频在线 | 天天综合日日夜夜 | 91久久精品日日躁夜夜躁国产 | 欧美在线资源 | 999国产| 一区二区成人国产精品 | 深爱激情亚洲 | 午夜久久久久久久久 | 天天爽夜夜爽精品视频婷婷 | 亚洲精品免费播放 | av免费试看 | 亚洲一区视频免费观看 | 欧美福利片在线观看 | 亚洲欧美视频网站 | 欧美一区二区在线刺激视频 | 少妇高潮冒白浆 | 很污的网站 | 久久精品一区二区三区国产主播 | 成人网看片 | 激情综合久久 | 日本三级不卡 | 97视频资源 | 欧美日韩久久久 | 五月天激情视频在线观看 | 中文字幕av播放 | 1000部国产精品成人观看 | 国产99久久九九精品 | 天堂av网站 | 日韩成人免费观看 | 91精品一 | 亚洲国产影院 | 一级片在线 | 狠狠操欧美 | 在线观看免费 | 久草在线视频首页 | av中文在线影视 | 成人av.com | 久草在线一免费新视频 | 99视频在线精品国自产拍免费观看 | 欧美a在线免费观看 | 午夜av在线免费 | 亚洲激情在线观看 | 国产视频亚洲精品 | 欧美日韩一区二区三区免费视频 | 国产乱对白刺激视频在线观看女王 | 亚洲传媒在线 | 热久久这里只有精品 | 91九色视频在线观看 | 欧美一级视频在线观看 | 免费在线观看成人av | 西西4444www大胆视频 | 美女黄久久 | 色资源在线| 在线国产高清 | 日本精品中文字幕 | 国产一区免费观看 | av一级在线 | 国产免费区 | 美女网站在线看 | 看黄色91 | 狠狠的干狠狠的操 | 成人亚洲综合 | 92中文资源在线 | 日韩电影一区二区三区 | 成人黄色av免费在线观看 | 日韩精品免费专区 | 日韩精品一区二区免费视频 | 欧美一级片在线观看视频 | 伊人影院在线观看 | 日本精品在线看 | 日韩欧美在线观看一区二区三区 | 96看片| 麻豆视频免费入口 | 久久久久免费精品国产小说色大师 | 天天艹天天爽 | 欧美成人xxxxx | 91人人人| 久久国产精品精品国产色婷婷 | 五月天婷婷在线播放 | 99精品热视频只有精品10 | 亚洲色图 校园春色 | 爱情影院aqdy鲁丝片二区 | 久久久久网址 | 久久久久一区 | 蜜臀久久99精品久久久无需会员 | 在线观看国产永久免费视频 | 丁香激情婷婷 | 99热精品国产一区二区在线观看 | 国产精品久久一区二区无卡 | 日韩和的一区二在线 | 超碰激情在线 | 欧美精品网站 | 婷婷网五月天 | 91成人网在线观看 | 黄色一级大片在线免费看国产一 | 日韩av成人在线 | 国产精品美女久久久久久久久久久 | 免费情缘 | 波多野结衣资源 | 久久99国产精品久久99 | 亚洲黄色免费 | 久久综合导航 | 黄色网在线播放 | www夜夜操 | 中文av网站 | 成人性生爱a∨ | 91九色porny蝌蚪视频 | 国产精品永久免费在线 | 色在线亚洲| 久久久久久高潮国产精品视 | 国产精品入口麻豆 | 91干干干 | 国产一区二区三区免费观看视频 | 在线观看日韩中文字幕 | 天堂av网址| 久久精品国产精品亚洲 | 国产91在线免费视频 | 国产高清视频网 | 亚洲精品视频在线观看视频 | 日韩三级免费 | 99久精品| 亚洲欧美婷婷六月色综合 | 日本mv大片欧洲mv大片 | 久久免费成人精品视频 | 四虎www. | 久久观看最新视频 | 国产精品久久久久久久久久东京 | 摸bbb搡bbb搡bbbb | 揉bbb玩bbb少妇bbb | 91在线视频观看免费 | 国产高清福利在线 | 久久精品国产99 | 国产一级免费观看视频 | 91精品办公室少妇高潮对白 | 国产99久久九九精品 | 色综合久久久久综合体桃花网 | 国产精品午夜久久 | 麻豆国产精品一区二区三区 | 国产精品久久久久久久av电影 | 在线免费观看视频一区 | 日韩精品久久久久久久电影99爱 | 黄色成人在线 | 欧美中文字幕第一页 | 天天干一干 | 国产在线欧美 | 欧美日韩成人 | 免费色网| 国产精品福利久久久 | 夜夜爽夜夜操 | 日本在线中文在线 | 天天躁天天操 | 精品在线免费观看 | 99久久婷婷国产精品综合 | 国产视频第二页 | 亚洲六月丁香色婷婷综合久久 | 亚洲激情影院 | 亚洲一区二区黄色 | 极品中文字幕 | 91天天操 | 99精品免费网 | 成人免费观看大片 | 日韩在线视频线视频免费网站 | 精品国产乱码久久久久久浪潮 | 91九色国产 | 日韩色综合| 啪啪免费试看 | 超碰在线官网 | 国产精品1区2区在线观看 | 天天操天天干天天综合网 | 日韩精品大片 | 日韩专区av | 欧美日韩精品免费观看 | 四虎成人精品永久免费av九九 | 色婷婷综合久久久中文字幕 | 一级黄网| 欧美一区三区四区 | 丁香资源影视免费观看 | 伊人国产在线播放 | 免费看毛片在线 | 国产精品一区二区免费视频 | 日韩专区视频 | 婷婷在线播放 | 日韩精品一区二区三区高清免费 | 91在线看| 久久伊人八月婷婷综合激情 | 99视频精品全部免费 在线 | 亚洲黄色区 | 久久免费99精品久久久久久 | 亚洲高清国产视频 | 最新av中文字幕 | 国产精品一区二区在线看 | 91成年视频 | 91av在线视频免费观看 | 一区二区视频免费在线观看 | av中文字幕剧情 | 日韩精品免费一区二区 | 国产精品99久久久久久久久久久久 | 国产亚洲精品久久久久秋 | www.激情五月.com | 99精品视频播放 | 亚州国产精品久久久 | 五月天色站 | 丰满少妇在线观看 | 欧美高清视频不卡网 | 99久久99视频只有精品 | 国产精品乱码久久久 | 国产96在线 | 99色婷婷| 免费人成在线观看 | 欧美激情综合色 | 在线免费av播放 | 欧美日韩视频在线播放 | 一区二区三区 亚洲 | 日韩高清在线一区 | 亚洲免费专区 | 天堂av色婷婷一区二区三区 | 丁香婷婷深情五月亚洲 | 国产精品18久久久 | 精品在线观看视频 | 一区二区在线电影 | 国产在线播放一区 | 青青草视频精品 | 国产精品色婷婷视频 | 国产黄色精品在线观看 | 成片免费观看视频 | 久久免费看a级毛毛片 | 欧美日韩裸体免费视频 | 亚洲精品黄网站 | 久久激情综合网 | 亚洲黄色软件 | 黄色高清视频在线观看 | 97夜夜澡人人双人人人喊 | 狠狠躁夜夜躁人人爽超碰97香蕉 | 人人爽久久久噜噜噜电影 | 日韩一区二区三区免费视频 | 九热在线| 中文字幕中文字幕在线中文字幕三区 | 激情网综合 | 国产精品国产毛片 | 免费男女羞羞的视频网站中文字幕 | 亚洲精品久久久久中文字幕m男 | 国产成人综| 欧美亚洲精品在线观看 | 免费亚洲精品 | 97小视频| 国产黄网在线 | 午夜精品久久久99热福利 | 日本午夜免费福利视频 | 丁香导航| 久久久久亚洲精品中文字幕 | 成年人在线看片 | 在线播放av网址 | 欧美一级片免费观看 | 久久免费视频网站 | 成人av影院在线观看 | 成人在线播放网站 | 黄av免费在线观看 | 日日日干| 国产精品久久久久久久久久东京 | 性色视频在线 | 婷婷在线视频观看 | 久久综合五月天 | 99视频在线看| 日韩视| 精品国产欧美一区二区 | 91视频高清 | 免费看黄网站在线 | 日韩精品中文字幕在线播放 | 中文字幕日韩免费视频 | 国产一区二三区好的 | 日韩电影一区二区在线观看 | 久久99久久久久 | 91大神电影 | 麻豆一级视频 | 91片黄在线观 | 在线看国产视频 | 精品国产一区二区三区不卡 | 亚洲精品中文字幕在线 | 免费av片在线 | 日日干干夜夜 | 久久久精品 一区二区三区 国产99视频在线观看 | 日韩乱理 | 99久久精品国产免费看不卡 | 69国产精品成人在线播放 | 久久综合免费视频影院 | 丁香久久久 | 欧美日韩国产精品一区 | 日韩免费福利 | 久久免费的精品国产v∧ | 日日操网站 | 亚洲在线日韩 | 成人h电影 | 国产第一页精品 | 91精品久久久久久久久 | 麻豆 free xxxx movies hd| 特级黄色电影 | 99色视频 | 97在线免费| 射久久| 国产精品毛片一区二区 | av黄色国产| 欧美久久久久久久久久久 | 探花视频在线观看 | 日韩av不卡在线观看 | 超碰国产在线 | 国产字幕在线看 | 国产一区免费在线 | 免费在线观看不卡av | 97人人爽人人 | 精品亚洲网 | 欧美a级成人淫片免费看 | 亚洲一级片 | 日本中文在线观看 | 国产免费三级在线观看 | 免费观看国产视频 | 精品久久久久久亚洲综合网站 | 四虎国产精品成人免费影视 | 欧美国产不卡 | 久久久精品网 | 蜜臀av性久久久久蜜臀aⅴ流畅 | 欧美网址在线观看 | 欧美日韩在线播放一区 | 激情综合网婷婷 | 好看的国产精品视频 | 精品久久久久久久久久 | 深爱婷婷| 久久久久免费精品 | 日本中文字幕观看 | 狠狠躁日日躁狂躁夜夜躁 | 午夜精品久久久久久久久久久 | 特级西西444www大胆高清无视频 | 婷婷激情综合五月天 | 五月婷婷,六月丁香 | 日韩免费在线播放 | 精品成人国产 | 久久综合免费 | 国内99视频| 久久dvd| 超碰在线最新地址 | 婷婷色网站 | 手机在线观看国产精品 | 久久人人爽人人爽人人片av免费 | 日本久久成人中文字幕电影 | 91在线视频精品 | 久久国产乱 | 亚洲精品午夜久久久久久久久久久 | 欧美精品免费视频 | 亚洲精品电影在线 | 久久人人爽人人 | 中文字幕你懂的 | 久久五月情影视 | 免费一级片观看 | 国产精久久久 | 久久dvd| 91九色蝌蚪在线 | 韩国av免费 | 国产视频二 | 91九色国产 | 天堂资源在线观看视频 | 久久成人国产精品入口 | 国产美女网站视频 | 婷婷av网站| 成人久久精品视频 | 久久国产精品免费看 | 国产视频亚洲视频 | 久久久穴| 麻豆视频在线免费观看 | 日韩一区二区三区视频在线 | 久久午夜国产精品 | 天海冀一区二区三区 | 在线只有精品 | 中文字幕精品一区二区三区电影 | 一区二区三区高清在线观看 | 男女激情片在线观看 | 久久久免费高清视频 | 国产男女免费完整视频 | 久久久久国产精品厨房 | 日韩欧美电影 | 亚洲午夜精品久久久久久久久 | 亚洲精品综合欧美二区变态 | 国产精品久久一 | 亚洲一区二区三区91 | 性色av一区二区三区在线观看 | 中文字幕在线视频国产 | 在线看中文字幕 | 免费观看不卡av | 亚洲人成人在线 | 国产精品毛片一区二区在线 | 久久 精品一区 | 91精品夜夜 | 丁香激情综合久久伊人久久 | 国产免费a | 久草手机视频 | 国产精品欧美久久久久无广告 | 日批视频在线播放 | 五月天丁香亚洲 | 久久精品国产精品亚洲 | 美女黄色网在线播放 | 91国内在线视频 | 日b视频在线观看网址 | 国产精品人成电影在线观看 | 中文字幕免费国产精品 | 欧美精品久久99 | 精品久久国产精品 | 免费在线观看成人小视频 | 伊人狠狠 | 国产精品久久久久久久免费观看 | 国产97碰免费视频 | 人人插人人费 | 好看av在线 | 欧美日韩一区二区视频在线观看 | 青草视频在线播放 | 欧美精品你懂的 | 国产精品久久久久av免费 | 精品 一区 在线 | 欧美一级免费片 | 在线观看第一页 | 黄色小网站在线 | 黄色av影院 | 婷婷伊人综合 | 免费亚洲黄色 | 九九热视频在线播放 | 免费中午字幕无吗 | 久草青青在线观看 | 国产美女精品视频 | 国产午夜精品理论片在线 | 久草精品视频 | 欧美在线视频免费 | 91亚瑟视频 | 狠狠色丁香婷婷综合橹88 | 在线国产一区二区 | 夜夜夜夜爽 | 国产大片免费久久 | 成人夜晚看av | 狠狠色丁香婷婷综合欧美 | 久久久久免费精品国产小说色大师 | 一级精品视频在线观看宜春院 | 成人v | 国产做爰视频 | 欧美性生活免费 | 欧美综合在线视频 | 黄色免费网站大全 | 91av在| 国产 中文 日韩 欧美 | a级国产乱理论片在线观看 伊人宗合网 | 亚洲午夜久久久影院 | 97超碰在线久草超碰在线观看 | 天天做天天看 | 夜夜操狠狠操 | 亚洲精品免费在线 | 国产亚洲精品精品精品 | 国产精品女同一区二区三区久久夜 | 免费观看91视频 | 亚洲精品视频观看 | 麻豆国产精品va在线观看不卡 | 日韩成人中文字幕 | 国产999久久久 | 天天爱天天射 | 国产在线欧美在线 | 91一区啪爱嗯打偷拍欧美 | 国产乱对白刺激视频在线观看女王 | 国产在线高清 | 成人av在线影院 | 97精品国自产拍在线观看 | 日本中文字幕在线观看 | 精品人人爽 | 国产字幕在线看 | 久久久久亚洲精品成人网小说 | 热久久国产精品 | 国产成人精品一区二区三区 | 亚洲区精品视频 | 少妇性xxx| 国产传媒一区在线 | 中文在线a√在线 | 波多野结衣最新 | 日本高清免费中文字幕 | 7777精品伊人久久久大香线蕉 | 91免费视频网站在线观看 | 色夜视频 | 久久国产精品免费 | 狠狠色噜噜狠狠 | 久久99影院 | 成人一级黄色片 | 精品久久久成人 | 精品国产三级 | 亚洲精品午夜一区人人爽 | 亚洲综合干 | 精品国产伦一区二区三区观看说明 | 夜夜婷婷| 久草视频播放 | 日韩在线观看免费 | 99爱视频 | 国产一区视频在线观看免费 | www.香蕉视频 | 在线中文字幕播放 | 国产免费专区 | 九色一区二区 | 探花系列在线 | 国产精品国产三级国产aⅴ入口 | 国产精品自产拍在线观看网站 | 天天天射 | 97色婷婷人人爽人人 | 日韩精品一区二区三区不卡 | 久久综合九色综合97婷婷女人 | 97香蕉超级碰碰久久免费软件 | 精品成人国产 | 精品播放 | 国产伦理一区二区三区 | 亚洲精品乱码白浆高清久久久久久 | 久草免费看 | 香蕉视频在线播放 | 成年人免费av | 九色最新网址 | www久久精品 | 亚洲成人av片在线观看 | 亚洲精品女人久久久 | 五月天六月色 | 99草视频在线观看 | 久久国产精品一区二区 | 狠狠色丁香婷婷综合视频 | 中文字幕欧美日韩va免费视频 | 97超碰在线久草超碰在线观看 | 一区二区不卡在线观看 | 97av在线视频 | 久久免费黄色大片 | 欧美一级免费 | 91丨九色丨蝌蚪丰满 | 欧美爽爽爽| 九九免费精品视频在线观看 | 久久综合国产伦精品免费 | 视频在线在亚洲 | 国产高清第一页 | 精品久久久久久亚洲综合网站 | 欧美日韩在线播放 | 亚洲人成在线观看 | 欧美精品天堂 | 亚洲伊人av | 中文字幕亚洲国产 | 黄毛片在线观看 | 中文国产字幕在线观看 | 成人av在线资源 | 在线免费黄色毛片 | 美国三级黄色大片 | 美女黄色网在线播放 | 久久精品中文字幕 | 婷婷丁香六月天 | 四虎在线影视 | 日韩精品高清不卡 | 香蕉精品视频在线观看 | 黄色av观看 | 黄色片网站大全 | 亚洲视频免费在线观看 | 成人在线免费视频观看 | 91免费版在线观看 | 久久69av | 狠狠躁夜夜av | 91试看| 日韩aⅴ视频 | 97国产超碰在线 | www五月天婷婷 | 91九色精品国产 | 日韩在线一区二区免费 | 国产女人免费看a级丨片 | 精品国产视频在线观看 | 欧美一二三视频 | 丁香激情网 | 97视频在线观看成人 | 美女视频网站久久 | 久久国产精品免费 | 久久99久久99精品免视看婷婷 | 免费亚洲黄色 | 91亚洲精品国偷拍自产在线观看 | 欧美一性一交一乱 | 天天插天天干天天操 | 在线观看香蕉视频 | 免费的国产精品 | 992tv又爽又黄的免费视频 | 超碰人人乐| 日韩欧美国产激情在线播放 | 一级片视频在线 | 成人在线免费视频观看 | 婷婷开心久久网 | 麻豆视频免费在线 | 亚洲精品三级 | 精品二区久久 | 亚洲国产精品成人va在线观看 | 伊人影院av| 久久国产精品影片 | 日韩一区二区久久 | 久久午夜国产 | 久草新在线 | 国产黄色成人av | 特级毛片在线观看 | 激情婷婷综合 | 国产小视频网站 | 超碰人人99 | 欧美一级欧美一级 | 亚洲狠狠 | 在线观看视频你懂的 | 一级α片免费看 | 日韩免费电影网站 | 国产精品免费在线观看视频 | 91激情 | 精品天堂av | 国产成人精品国内自产拍免费看 | 亚洲va男人天堂 | 中文字幕亚洲欧美日韩2019 | 成人精品视频 | 国产中文字幕视频在线观看 | 国产福利小视频在线 | 91亚洲影院 | 亚洲免费激情 | av一级片| 天天干夜夜夜操天 | 在线观看免费成人av | 国产精品国内免费一区二区三区 | 91视视频在线直接观看在线看网页在线看 | 片网址 | 狠狠狠狠狠狠狠狠 | 久久精品成人 | 一二三区视频在线 | 91自拍视频在线 | 免费观看91视频大全 | 91精品视频观看 | 日韩电影在线一区 | 亚洲aⅴ乱码精品成人区 | 久草精品视频在线播放 | 国产精品免费在线播放 | 亚洲a资源 | 国产91影视 | 国产精品麻豆果冻传媒在线播放 | 很污的网站 | 91福利视频一区 | 一区免费观看 | 日韩一区视频在线 | 在线看免费 | 狠狠色噜噜狠狠狠狠 | 国产精品一区电影 | 深爱开心激情 | 人人要人人澡人人爽人人dvd | 亚洲国产中文在线 | 97超碰在线久草超碰在线观看 | a级免费观看 | 欧美成人tv | 91热精品| 成人亚洲综合 | 日韩一级电影在线 | 午夜精品久久久久99热app | 成人a在线观看高清电影 | 精品久久久久久电影 | 欧美色道| 午夜精品久久久久久久99 | 女人高潮特级毛片 | 久久免费看a级毛毛片 | 最近中文字幕高清字幕免费mv | av中文字幕在线免费观看 | 91在线麻豆 | 欧美大片mv免费 | 国产精品美女999 | 免费高清在线观看电视网站 | 天天av天天 | 国产美女精品人人做人人爽 | 999抗病毒口服液 | 成人教育av | 国产中文在线字幕 | www.狠狠| 久久精品香蕉 | 天天综合五月天 | 手机成人在线电影 | 在线综合 亚洲 欧美在线视频 | 国产 日韩 欧美 中文 在线播放 | 黄色网免费| 日韩精品视频在线观看免费 | 韩国av一区二区 | 欧美大码xxxx |