午夜视频免费看_日韩三级电影网站_国产精品久久一级_亚洲一级在线播放_人妻体内射精一区二区三区_91夜夜揉人人捏人人添红杏_91福利在线导航_国产又粗又猛又黄又爽无遮挡_欧美日韩一区在线播放_中文字幕一区二区三区四区不卡 _日日夜夜精品视频免费观看_欧美韩日一区二区三区

主頁 > 知識庫 > HTML5錄音實踐總結(Preact)

HTML5錄音實踐總結(Preact)

熱門標簽:如何獲取地圖標注客戶 機器人外呼系統存在哪些能力 平涼地圖標注位置怎么弄 電話機器人黑斑馬免費 電話機器人電銷系統掙話費 南昌仁和怎么申請開通400電話 只辦理400電話 高德地圖標注地點糾錯 拓展地圖標注

獲取 PCM 數據

處理 PCM 數據

Float32Int16

ArrayBufferBase64

PCM 文件播放

重采樣

PCMMP3

PCMWAV

短時能量計算

Web Worker優化性能

音頻存儲(IndexedDB)

WebView 開啟 WebRTC

獲取 PCM 數據

查看 DEMO

https://github.com/deepkolos/pc-pcm-wave

樣例代碼:

const mediaStream = await window.navigator.mediaDevices.getUserMedia({
    audio: {
		// sampleRate: 44100, // 采樣率 不生效需要手動重采樣
        channelCount: 1, // 聲道
        // echoCancellation: true,
        // noiseSuppression: true, // 降噪 實測效果不錯
    },
})
const audioContext = new window.AudioContext()
const inputSampleRate = audioContext.sampleRate
const mediaNode = audioContext.createMediaStreamSource(mediaStream)

if (!audioContext.createScriptProcessor) {
	audioContext.createScriptProcessor = audioContext.createJavaScriptNode
}
// 創建一個jsNode
const jsNode = audioContext.createScriptProcessor(4096, 1, 1)
jsNode.connect(audioContext.destination)
jsNode.onaudioprocess = (e) => {
    // e.inputBuffer.getChannelData(0) (left)
    // 雙通道通過e.inputBuffer.getChannelData(1)獲取 (right)
}
mediaNode.connect(jsNode)

簡要流程如下:

start=>start: 開始
getUserMedia=>operation: 獲取MediaStream
audioContext=>operation: 創建AudioContext
scriptNode=>operation: 創建scriptNode并關聯AudioContext
onaudioprocess=>operation: 設置onaudioprocess并處理數據
end=>end: 結束

start->getUserMedia->audioContext->scriptNode->onaudioprocess->end

停止錄制只需要把 audioContext 掛在的 node 卸載即可,然后把存儲的每一幀數據合并即可產出 PCM 數據

jsNode.disconnect()
mediaNode.disconnect()
jsNode.onaudioprocess = null

PCM 數據處理

通過 WebRTC 獲取的 PCM 數據格式是 Float32 的, 如果是雙通道錄音的話, 還需要增加合并通道

const leftDataList = [];
const rightDataList = [];
function onAudioProcess(event) {
  // 一幀的音頻PCM數據
  let audioBuffer = event.inputBuffer;
  leftDataList.push(audioBuffer.getChannelData(0).slice(0));
  rightDataList.push(audioBuffer.getChannelData(1).slice(0));
}

// 交叉合并左右聲道的數據
function interleaveLeftAndRight(left, right) {
  let totalLength = left.length + right.length;
  let data = new Float32Array(totalLength);
  for (let i = 0; i < left.length; i++) {
    let k = i * 2;
    data[k] = left[i];
    data[k + 1] = right[i];
  }
  return data;
}

Float32 轉 Int16

const float32 = new Float32Array(1)
const int16 = Int16Array.from(
	float32.map(x => (x > 0 ? x * 0x7fff : x * 0x8000)),
)

arrayBuffer 轉 Base64

注意: 在瀏覽器上有個 btoa() 函數也是可以轉換為 Base64 但是輸入參數必須為字符串, 如果傳遞 buffer 參數會先被 toString() 然后再 Base64 , 使用 ffplay 播放反序列化的 Base64 , 會比較刺耳

使用 base64-arraybuffer 即可完成

import { encode } from 'base64-arraybuffer'

const float32 = new Float32Array(1)
const int16 = Int16Array.from(
	float32.map(x => (x > 0 ? x * 0x7fff : x * 0x8000)),
)
console.log(encode(int16.buffer))

驗證 Base64 是否正確, 可以在 node 下把產出的 Base64 轉換為 Int16 的 PCM 文件, 然后使用 FFPlay 播放, 看看音頻是否正常播放

PCM 文件播放

# 單通道 采樣率:16000 Int16
ffplay -f s16le -ar 16k -ac 1 test.pcm

# 雙通道 采樣率:48000 Float32
ffplay -f f32le -ar 48000 -ac 2 test.pcm

重采樣/調整采樣率

雖然 getUserMedia 參數可設置采樣率, 但是在最新Chrome也不生效, 所以需要手動做個重采樣

const mediaStream = await window.navigator.mediaDevices.getUserMedia({
    audio: {
    	// sampleRate: 44100, // 采樣率 設置不生效
        channelCount: 1, // 聲道
        // echoCancellation: true, // 減低回音
        // noiseSuppression: true, // 降噪, 實測效果不錯
    },
})

使用 wave-resampler 即可完成

import { resample } from 'wave-resampler'

const inputSampleRate =  44100
const outputSampleRate = 16000
const resampledBuffers = resample(
    // 需要onAudioProcess每一幀的buffer合并后的數組
	mergeArray(audioBuffers),
	inputSampleRate,
	outputSampleRate,
)

PCM 轉 MP3

import { Mp3Encoder } from 'lamejs'

let mp3buf
const mp3Data = []
const sampleBlockSize = 576 * 10 // 工作緩存區, 576的倍數
const mp3Encoder = new Mp3Encoder(1, outputSampleRate, kbps)
const samples = float32ToInt16(
  audioBuffers,
  inputSampleRate,
  outputSampleRate,
)

let remaining = samples.length
for (let i = 0; remaining >= 0; i += sampleBlockSize) {
  const left = samples.subarray(i, i + sampleBlockSize)
  mp3buf = mp3Encoder.encodeBuffer(left)
  mp3Data.push(new Int8Array(mp3buf))
  remaining -= sampleBlockSize
}

mp3Data.push(new Int8Array(mp3Encoder.flush()))
console.log(mp3Data)

// 工具函數
function float32ToInt16(audioBuffers, inputSampleRate, outputSampleRate) {
  const float32 = resample(
    // 需要onAudioProcess每一幀的buffer合并后的數組
    mergeArray(audioBuffers),
    inputSampleRate,
    outputSampleRate,
  )
  const int16 = Int16Array.from(
    float32.map(x => (x > 0 ? x * 0x7fff : x * 0x8000)),
  )
  return int16
}

使用 lamejs 即可, 但是體積較大(160+KB), 如果沒有存儲需求可使用 WAV 格式

> ls -alh
-rwxrwxrwx 1 root root  95K  4月 22 12:45 12s.mp3*
-rwxrwxrwx 1 root root 1.1M  4月 22 12:44 12s.wav*
-rwxrwxrwx 1 root root 235K  4月 22 12:41 30s.mp3*
-rwxrwxrwx 1 root root 2.6M  4月 22 12:40 30s.wav*
-rwxrwxrwx 1 root root  63K  4月 22 12:49 8s.mp3*
-rwxrwxrwx 1 root root 689K  4月 22 12:48 8s.wav*

PCM 轉 WAV

function mergeArray(list) {
  const length = list.length * list[0].length
  const data = new Float32Array(length)
  let offset = 0
  for (let i = 0; i < list.length; i++) {
    data.set(list[i], offset)
    offset += list[i].length
  }
  return data
}

function writeUTFBytes(view, offset, string) {
  var lng = string.length
  for (let i = 0; i < lng; i++) {
    view.setUint8(offset + i, string.charCodeAt(i))
  }
}

function createWavBuffer(audioData, sampleRate = 44100, channels = 1) {
  const WAV_HEAD_SIZE = 44
  const buffer = new ArrayBuffer(audioData.length * 2 + WAV_HEAD_SIZE)
  // 需要用一個view來操控buffer
  const view = new DataView(buffer)
  // 寫入wav頭部信息
  // RIFF chunk descriptor/identifier
  writeUTFBytes(view, 0, 'RIFF')
  // RIFF chunk length
  view.setUint32(4, 44 + audioData.length * 2, true)
  // RIFF type
  writeUTFBytes(view, 8, 'WAVE')
  // format chunk identifier
  // FMT sub-chunk
  writeUTFBytes(view, 12, 'fmt')
  // format chunk length
  view.setUint32(16, 16, true)
  // sample format (raw)
  view.setUint16(20, 1, true)
  // stereo (2 channels)
  view.setUint16(22, channels, true)
  // sample rate
  view.setUint32(24, sampleRate, true)
  // byte rate (sample rate * block align)
  view.setUint32(28, sampleRate * 2, true)
  // block align (channel count * bytes per sample)
  view.setUint16(32, channels * 2, true)
  // bits per sample
  view.setUint16(34, 16, true)
  // data sub-chunk
  // data chunk identifier
  writeUTFBytes(view, 36, 'data')
  // data chunk length
  view.setUint32(40, audioData.length * 2, true)

  // 寫入PCM數據
  let index = 44
  const volume = 1
  const { length } = audioData
  for (let i = 0; i < length; i++) {
    view.setInt16(index, audioData[i] * (0x7fff * volume), true)
    index += 2
  }
  return buffer
}

// 需要onAudioProcess每一幀的buffer合并后的數組
createWavBuffer(mergeArray(audioBuffers))

WAV 基本上是 PCM 加上一些音頻信息

簡單的短時能量計算

function shortTimeEnergy(audioData) {
  let sum = 0
  const energy = []
  const { length } = audioData
  for (let i = 0; i < length; i++) {
    sum += audioData[i] ** 2

    if ((i + 1) % 256 === 0) {
      energy.push(sum)
      sum = 0
    } else if (i === length - 1) {
      energy.push(sum)
    }
  }
  return energy
}

由于計算結果有會因設備的錄音增益差異較大, 計算出數據也較大, 所以使用比值簡單區分人聲和噪音

查看 DEMO

const NoiseVoiceWatershedWave = 2.3
const energy = shortTimeEnergy(e.inputBuffer.getChannelData(0).slice(0))
const avg = energy.reduce((a, b) => a + b) / energy.length

const nextState = Math.max(...energy) / avg > NoiseVoiceWatershedWave ? 'voice' : 'noise'

Web Worker 優化性能

音頻數據數據量較大, 所以可以使用 Web Worker 進行優化, 不卡 UI 線程

在 Webpack 項目里 Web Worker 比較簡單, 安裝 worker-loader 即可

preact.config.js

export default (config, env, helpers) => {
    config.module.rules.push({
        test: /\.worker\.js$/,
        use: { loader: 'worker-loader', options: { inline: true } },
      })
}

recorder.worker.js

self.addEventListener('message', event => {
  console.log(event.data)
  // 轉MP3/轉Base64/轉WAV等等
  const output = ''
  self.postMessage(output)
}

使用 Worker

async function toMP3(audioBuffers, inputSampleRate, outputSampleRate = 16000) {
  const { default: Worker } = await import('./recorder.worker')
  const worker = new Worker()
  // 簡單使用, 項目可以在recorder實例化的時候創建worker實例, 有并法需求可多個實例

  return new Promise(resolve => {
    worker.postMessage({
      audioBuffers: audioBuffers,
      inputSampleRate: inputSampleRate,
      outputSampleRate: outputSampleRate,
      type: 'mp3',
    })
    worker.onmessage = event => resolve(event.data)
  })
}

音頻的存儲

瀏覽器持久化儲存的地方有 LocalStorage 和 IndexedDB , 其中 LocalStorage 較為常用, 但是只能儲存字符串, 而 IndexedDB 可直接儲存 Blob , 所以優先選擇 IndexedDB ,使用 LocalStorage 則需要轉 Base64 體積將會更大

所以為了避免占用用戶太多空間, 所以選擇MP3格式進行存儲

> ls -alh
-rwxrwxrwx 1 root root  95K  4月 22 12:45 12s.mp3*
-rwxrwxrwx 1 root root 1.1M  4月 22 12:44 12s.wav*
-rwxrwxrwx 1 root root 235K  4月 22 12:41 30s.mp3*
-rwxrwxrwx 1 root root 2.6M  4月 22 12:40 30s.wav*
-rwxrwxrwx 1 root root  63K  4月 22 12:49 8s.mp3*
-rwxrwxrwx 1 root root 689K  4月 22 12:48 8s.wav*

IndexedDB 簡單封裝如下, 熟悉后臺的同學可以找個 ORM 庫方便數據讀寫

const indexedDB =
  window.indexedDB ||
  window.webkitIndexedDB ||
  window.mozIndexedDB ||
  window.OIndexedDB ||
  window.msIndexedDB

const IDBTransaction =
  window.IDBTransaction ||
  window.webkitIDBTransaction ||
  window.OIDBTransaction ||
  window.msIDBTransaction

const readWriteMode =
  typeof IDBTransaction.READ_WRITE === 'undefined'
    ? 'readwrite'
    : IDBTransaction.READ_WRITE

const dbVersion = 1
const storeDefault = 'mp3'

let dbLink

function initDB(store) {
  return new Promise((resolve, reject) => {
    if (dbLink) resolve(dbLink)

    // Create/open database
    const request = indexedDB.open('audio', dbVersion)

    request.onsuccess = event => {
      const db = request.result

      db.onerror = event => {
        reject(event)
      }

      if (db.version === dbVersion) resolve(db)
    }

    request.onerror = event => {
      reject(event)
    }

    // For future use. Currently only in latest Firefox versions
    request.onupgradeneeded = event => {
      dbLink = event.target.result
      const { transaction } = event.target

      if (!dbLink.objectStoreNames.contains(store)) {
        dbLink.createObjectStore(store)
      }

      transaction.oncomplete = event => {
        // Now store is available to be populated
        resolve(dbLink)
      }
    }
  })
}

export const writeIDB = async (name, blob, store = storeDefault) => {
  const db = await initDB(store)

  const transaction = db.transaction([store], readWriteMode)
  const objStore = transaction.objectStore(store)

  return new Promise((resolve, reject) => {
    const request = objStore.put(blob, name)
    request.onsuccess = event => resolve(event)
    request.onerror = event => reject(event)
    transaction.commit && transaction.commit()
  })
}

export const readIDB = async (name, store = storeDefault) => {
  const db = await initDB(store)

  const transaction = db.transaction([store], readWriteMode)
  const objStore = transaction.objectStore(store)

  return new Promise((resolve, reject) => {
    const request = objStore.get(name)
    request.onsuccess = event => resolve(event.target.result)
    request.onerror = event => reject(event)
    transaction.commit && transaction.commit()
  })
}

export const clearIDB = async (store = storeDefault) => {
  const db = await initDB(store)

  const transaction = db.transaction([store], readWriteMode)
  const objStore = transaction.objectStore(store)
  return new Promise((resolve, reject) => {
    const request = objStore.clear()
    request.onsuccess = event => resolve(event)
    request.onerror = event => reject(event)
    transaction.commit && transaction.commit()
  })
}

WebView 開啟 WebRTC

見 WebView WebRTC not working

webView.setWebChromeClient(new WebChromeClient(){
	@TargetApi(Build.VERSION_CODES.LOLLIPOP)
	@Override
	public void onPermissionRequest(final PermissionRequest request) {
		request.grant(request.getResources());
	}
});

到此這篇關于HTML5錄音實踐總結(Preact)的文章就介紹到這了,更多相關html5錄音內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關文章,希望大家以后多多支持腳本之家!

標簽:遼源 漯河 青島 西藏 棗莊 新疆 永州 池州

巨人網絡通訊聲明:本文標題《HTML5錄音實踐總結(Preact)》,本文關鍵詞  HTML5,錄音,實踐,總結,Preact,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《HTML5錄音實踐總結(Preact)》相關的同類信息!
  • 本頁收集關于HTML5錄音實踐總結(Preact)的相關信息資訊供網民參考!
  • 推薦文章
    永久av免费网站| 久久精品99国产精品酒店日本| 国产成人三级一区二区在线观看一| 国产一区在线免费观看| 色诱亚洲精品久久久久久| 一级一级黄色片| www.中文字幕| 在线免费观看一级片| 国产老头老太做爰视频| 日韩久久久久久久久| 青青草视频一区| 亚洲自拍偷拍九九九| 色视频www在线播放国产成人| 久久色免费在线视频| 国产精品一区二区男女羞羞无遮挡| 国产麻豆剧传媒精品国产| 日韩一级特黄毛片| 热99这里只有精品| 手机免费看av网站| 韩国福利视频一区| 亚洲精品国产福利| 亚洲变态欧美另类捆绑| 久久久久久久久久国产| 精品国产乱码久久久久久老虎 | 亚洲欧洲日韩综合| 韩国av中国字幕| 免费看黄色三级| 国产一区二区在线不卡| 国产欧美日韩综合精品一区二区| 欧美日韩一区二区三区不卡| 久久av中文字幕| 91免费看片在线| 久久影视电视剧免费网站清宫辞电视| 亚洲人成在线免费观看| 中文字幕久久精品| 色94色欧美sute亚洲线路一ni| 久久综合色综合88| 日韩经典中文字幕| 神马久久久久久久久久| 最新黄色av网址| 青青草手机在线视频| 欧美一区二区三区爽大粗免费| 欧美做受777cos| 日本超碰在线观看| 99久久精品国产一区二区成人| 欧美日韩加勒比精品一区| 欧美亚洲视频一区二区| 免费看涩涩视频| 男人的天堂一区| 日本黄色免费视频| 日产国产高清一区二区三区 | 久久久久成人精品| 国产精品偷伦视频免费观看国产| 中文字幕乱码一区二区免费| 亚洲黄色片视频| 欧美日韩精品区| 亚洲区自拍偷拍| 久久久久久久久久久久国产精品| 三上悠亚ssⅰn939无码播放| 老湿机69福利| 日韩av电影天堂| 亚洲国产中文字幕久久网| 欧美色视频日本版| 色婷婷av一区二区三区久久| 久久久久99精品成人片| 久久精品波多野结衣| 日韩av成人高清| 久久精品99国产精品| 国产成人精品影视| 国产精品素人一区二区| 日韩欧美激情在线| 欧美极品少妇xxxxⅹ高跟鞋| 五月天福利视频| 91在线视频免费播放| 青春草免费视频| 精品一区二区三区免费毛片爱| 亚洲日本欧美天堂| 91精品国产综合久久久久久 | 日日噜噜噜夜夜爽亚洲精品| 97超碰人人爱| 久久永久免费视频| 91亚洲永久精品| 日韩美女一区二区三区四区| 亚洲白拍色综合图区| yw.139尤物在线精品视频| 精品日韩电影| 高清视频一区| 特级毛片在线免费观看| 国产一卡二卡在线播放| 欧洲一区二区在线观看| 麻豆一区二区三区在线观看| 久久久九九九热| 性欧美videos| 老熟妇一区二区三区| 国产精品入口麻豆原神| 久久久久久免费精品| 给我看免费高清在线观看| 国产精品久久久爽爽爽麻豆色哟哟| 日本韩国欧美精品大片卡二| 久操视频免费看| 久久电影网站中文字幕| 欧美一级二级三级乱码| 国产成人亚洲综合| 99中文字幕在线| 国产又粗又猛又爽又黄的| 国产视频一区二区在线| 成人精品视频一区二区三区尤物| 国产成人无遮挡在线视频| av一区二区久久| 亚洲精品日产精品乱码不卡| 7m精品福利视频导航| 国产又黄又猛视频| 国产黄在线免费观看| 久久久久国产精品麻豆ai换脸 | 不卡的日韩av| 久久电影网电视剧免费观看| 韩国视频一区二区| 亚洲精品国产精品久久清纯直播 | 成人亚洲激情网| 91精品国产三级| 久久久久久久国产精品毛片| 风流老熟女一区二区三区| 亚洲成人手机在线| 在线精品日韩| 日韩 欧美 综合| 亚洲一二三区在线观看| 国产精品永久免费观看| 国产l精品国产亚洲区久久| 久久亚洲AV成人无码国产野外 | 国产日韩欧美精品在线| 午夜精品久久久久久久男人的天堂 | 亚洲成人av在线播放| 久久男人资源视频| 一本一生久久a久久精品综合蜜 | 国产成人午夜精品5599| 中文字幕在线成人| 国产又黄又粗又硬| 亚洲国产成人久久| 国产伦精品一区二区三区免费视频| 亚洲日本japanese丝袜| 一级黄色a视频| 欧美色视频日本高清在线观看| 91黄在线观看| 亚洲国产精品二区| 国产成人jvid在线播放| 欧美男人天堂网| 在线丨暗呦小u女国产精品| av在线com| 亚洲视屏在线观看| 一本久久精品一区二区| 91在线播放视频| 青青草免费观看视频| 日韩美女啊v在线免费观看| 欧日韩精品视频| 久久久久久国产三级电影| 五月天亚洲综合小说网| 欲求不满的岳中文字幕| 国产精品网站导航| 亚洲aⅴ日韩av电影在线观看| 好男人www社区| 久久www免费人成看片高清| 欧美激情一区二区三区久久久| 欧美精品日韩在线| 美女精品视频一区| 国产免费a视频| 国产精品精品一区二区三区午夜版 | 亚洲男人天堂久久| 亚洲电影av在线| 制服诱惑一区| 国产三级三级在线观看| 欧美绝品在线观看成人午夜影视| 国产在线青青草| 国产精品影视天天线| 亚洲精品乱码久久久久久久久| 欧美风情在线观看| 亚洲国产精品久久久久爰色欲| 青青青国产在线| 欧美日韩裸体免费视频| 欧美 日韩 国产一区| 国产三级久久久| 日本乱人伦a精品| 波多野结衣人妻| 伦理中文字幕亚洲| 日本欧美一区二区三区乱码 | 日本高清久久天堂| 日韩成人dvd| 欧美系列一区| 久久综合成人精品亚洲另类欧美| 亚洲精品免费网站| 日韩精品手机在线| 色偷偷88欧美精品久久久| 黄黄视频在线观看| 另类调教123区 | 国产精品久久久久久久美男| 超碰人人爱人人| 精品国产乱子伦| 欧美性黄网官网| 国内不卡一区二区三区| 黑人精品一区二区| 国产精品久久久久久搜索| 亚洲最大成人网站| 欧美日韩不卡一区| 三级在线视频观看| 国产欧美日韩另类一区| 国产精品美女在线| 天码人妻一区二区三区在线看| 亚洲日本护士毛茸茸| 欧美日韩在线一二三| 99久久伊人网影院| 日韩黄色片视频| 亚洲欧洲日韩av| 99热手机在线| 午夜影院在线观看欧美| 妺妺窝人体色www看人体| 在线观看国产一区二区三区| 国产成人精品一区二区| av免费在线观看不卡| 一区不卡字幕| 欧美一级日韩一级| 蜜臀久久久久久999| 国产黄色激情视频| 亚洲免费视频在线观看| 午夜精品久久久久久久96蜜桃| 成人激情视频在线播放| www.午夜激情| 青青久久aⅴ北条麻妃| 啪啪小视频网站| 一区二区精品视频在线观看| 国产亚洲欧美aaaa| 精品二区在线观看| 国产精品入口尤物| 国产99在线 | 亚洲| 色综合天天综合给合国产| 亚洲中文字幕无码一区二区三区| 六月婷婷色综合| 国产成人激情小视频| 色wwwwww| 成年人三级视频| aaa亚洲精品| 男女h黄动漫啪啪无遮挡软件| 成人在线综合网站| 国产精品视频久久久| 欧美成人手机视频| 日韩一卡二卡三卡四卡| av亚洲天堂网| 久久午夜羞羞影院免费观看| 久久精品日产第一区二区三区 | 国产亚洲欧美精品久久久久久| 884aa四虎影成人精品一区| 中文字幕视频三区| 亚洲免费电影在线| 国产乱子伦农村叉叉叉| 看片的网站亚洲| 国产精品高精视频免费| 久久精品国产亚洲av高清色欲| 欧美在线观看一区| 四川一级毛毛片| 亚洲黄色av一区| 国产一区二区片| 午夜视频你懂的| 亚洲精选免费视频| 88av.com| 亚洲三级免费电影| 乌克兰美女av| 色婷婷久久综合| 亚洲av成人片色在线观看高潮| 欧美日韩综合在线| 岛国毛片在线播放| 一区二区三区高清在线| 中文字幕永久视频| 亚洲一区二区三区视频在线播放 | 97人妻精品视频一区| 亚洲一区二区久久久| 在线国产视频一区| 欧美日韩情趣电影| 波多野结衣中文字幕在线播放| 欧美日韩aaaaaa| 亚洲无人区码一码二码三码| 午夜精品一区二区三区电影天堂 | 亚洲欧洲精品在线 | 尤物国产精品| 99久久久免费精品国产一区二区| 99在线观看视频网站| 污视频在线免费观看| 国产高清一区视频| 成人国产精品视频| 无码人妻精品一区二区三区在线| 99国产精品国产精品久久| 国产免费一区二区三区| 天天av天天翘| 一卡二卡3卡四卡高清精品视频| 亚洲精品日韩专区silk| 熟女少妇精品一区二区| 欧美一区二区三区喷汁尤物| 亚洲综合色一区| 日韩在线视频免费观看| 影音先锋在线国产| 国产日韩专区在线| 久久综合久久久久88| 国产欧美激情视频| 日韩电影中文字幕av| 欧美成人精品欧美一级| 国产精品99久久久久久白浆小说| 久久国产精品区| 国产精品69久久久| 欧美精选一区二区| 小向美奈子av| 国产伦精品免费视频| 日本精品一二三区| 久久手机视频| 午夜精品久久久久久久91蜜桃| 欧美老少做受xxxx高潮| 国产中文字幕免费| 1区1区3区4区产品乱码芒果精品| 久久精品一区蜜桃臀影院| 久久久国产欧美| 一区二区三欧美| 日韩国产欧美一区二区三区| 国产中文字幕乱人伦在线观看| 51午夜精品国产| 日韩精品久久久久久久酒店| 亚洲a在线播放| 亚洲视频在线观看三级| 911国产在线| 亚洲精品免费一区二区三区| 久久亚洲私人国产精品va媚药| 日本少妇一级片| 亚洲欧美激情四射在线日| 日本欧洲一区二区| 久久久精品成人| 日本在线观看天堂男亚洲| 97精品久久久午夜一区二区三区| 人体私拍套图hdxxxx| 国模私拍视频一区| 99久久综合色| www.色小姐com| 污视频在线免费观看一区二区三区| 在线亚洲欧美专区二区| 国产色在线视频| 欧美与动交zoz0z| 亚洲精品视频在线观看视频| 天天操天天干天天舔| 少妇av一区二区三区无码| 日韩在线精品一区| 91蜜桃免费观看视频| 黄色一级片中国| 欧美综合77777色婷婷| 在线影视一区二区三区| 97免费在线观看视频| 欧美午夜精品理论片a级大开眼界 欧美午夜精品久久久久免费视 | 色婷婷**av毛片一区| 国产清纯美女被跳蛋高潮一区二区久久w | 久久久久久国产精品免费播放| 久久久综合香蕉尹人综合网| 欧美日韩在线电影| 免费看欧美女人艹b| 精品人妻一区二区免费| 国产成人精品a视频一区www| 亚洲美腿欧美偷拍| 中文在线免费观看| 青青草成人免费在线视频| 久久久久久久久久国产精品| 91在线一区二区| 亚洲免费在线视频观看| www..com日韩| 国产成人精品免费久久久久| 亚洲精品免费看| jlzzjlzzjlzz亚洲人| 久久久久亚洲av无码专区桃色| 国产一区二区黄色| 深夜福利91大全| 亚洲在线视频免费观看| www.黄色片| caoporm在线视频| 国产一区二区三区奇米久涩| 日韩电影中文字幕在线观看| 中文字幕视频一区| 污污网站免费在线观看| 亚洲欧美激情一区二区三区| 国产精品一二区| 69堂精品视频| 国产精品乱子久久久久| 国产精品久久久久毛片| 麻豆av免费观看| 国产青青在线视频| 91中文字幕在线| 日韩最新av在线| 日韩欧美在线视频免费观看| 亚洲黄色小说网| 天海翼在线视频| 日本精品一区在线| 四虎精品欧美一区二区免费| 久久全国免费视频| 欧美一区二区不卡视频| 亚洲精选视频免费看| 好吊视频一区二区三区| 日本少妇全体裸体洗澡| 美女久久久久久久久| 色哟哟免费网站| 国产精品香蕉av| 亚洲一区二区福利| 欧美日韩亚洲精品一区二区三区| 91在线porny国产在线看| 老司机午夜精品视频在线观看| 国产精品30p| brazzers精品成人一区| 色播五月激情五月| 日韩最新中文字幕| 成人高h视频在线| 欧美中文在线视频|