亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > iOS > 正文

iOS音樂播放器實現代碼完整版

2019-10-21 18:41:06
字體:
來源:轉載
供稿:網友

本文實例為大家分享了iOS實現音樂播放器的具體代碼,供大家參考,具體內容如下

audio_queue.cpp

/* * This file is part of the FreeStreamer project, * (C)Copyright 2011-2013 Matias Muhonen. * See the file ''LICENSE'' for using the code. * * Part of the code in this file has been rewritten from * the AudioFileStreamExample / afsclient.cpp * example, Copyright © 2007 Apple Inc. * * The threadless playback has been adapted from * Alex Crichton's AudioStreamer. */#include "audio_queue.h"#include <cassert>//#define AQ_DEBUG 1#if !defined (AQ_DEBUG) #define AQ_TRACE(...) do {} while (0)#else #define AQ_TRACE(...) printf(__VA_ARGS__)#endifnamespace astreamer { typedef struct queued_packet { AudioStreamPacketDescription desc; struct queued_packet *next; char data[];} queued_packet_t; /* public */  Audio_Queue::Audio_Queue() : m_delegate(0), m_state(IDLE), m_outAQ(0), m_fillBufferIndex(0), m_bytesFilled(0), m_packetsFilled(0), m_buffersUsed(0), m_processedPacketsSizeTotal(0), m_processedPacketsCount(0), m_audioQueueStarted(false), m_waitingOnBuffer(false), m_queuedHead(0), m_queuedTail(0), m_lastError(noErr){ for (size_t i=0; i < AQ_BUFFERS; i++) {  m_bufferInUse[i] = false; }} Audio_Queue::~Audio_Queue(){ stop(true);  cleanup();} bool Audio_Queue::initialized(){ return (m_outAQ != 0);} void Audio_Queue::start(){ // start the queue if it has not been started already if (m_audioQueueStarted) {  return; }    OSStatus err = AudioQueueStart(m_outAQ, NULL); if (!err) {  m_audioQueueStarted = true;  m_lastError = noErr; } else {  AQ_TRACE("%s: AudioQueueStart failed!/n", __PRETTY_FUNCTION__);  m_lastError = err; }} void Audio_Queue::pause(){ if (m_state == RUNNING) {  if (AudioQueuePause(m_outAQ) != 0) {   AQ_TRACE("%s: AudioQueuePause failed!/n", __PRETTY_FUNCTION__);  }  setState(PAUSED); } else if (m_state == PAUSED) {  AudioQueueStart(m_outAQ, NULL);  setState(RUNNING); }} void Audio_Queue::stop(){ stop(true);}void Audio_Queue::stop(bool stopImmediately){ if (!m_audioQueueStarted) {  AQ_TRACE("%s: audio queue already stopped, return!/n", __PRETTY_FUNCTION__);  return; } m_audioQueueStarted = false;  AQ_TRACE("%s: enter/n", __PRETTY_FUNCTION__); if (AudioQueueFlush(m_outAQ) != 0) {  AQ_TRACE("%s: AudioQueueFlush failed!/n", __PRETTY_FUNCTION__); }  if (stopImmediately) {  AudioQueueRemovePropertyListener(m_outAQ,           kAudioQueueProperty_IsRunning,           audioQueueIsRunningCallback,           this); }  if (AudioQueueStop(m_outAQ, stopImmediately) != 0) {  AQ_TRACE("%s: AudioQueueStop failed!/n", __PRETTY_FUNCTION__); }  if (stopImmediately) {  setState(IDLE); }  AQ_TRACE("%s: leave/n", __PRETTY_FUNCTION__);} double Audio_Queue::packetDuration(){ return m_streamDesc.mFramesPerPacket / m_streamDesc.mSampleRate;} unsigned Audio_Queue::timePlayedInSeconds(){ unsigned timePlayed = 0;  AudioTimeStamp queueTime; Boolean discontinuity;  OSStatus err = AudioQueueGetCurrentTime(m_outAQ, NULL, &queueTime, &discontinuity); if (err) {  goto out; }  timePlayed = queueTime.mSampleTime / m_streamDesc.mSampleRate; out: return timePlayed;} unsigned Audio_Queue::bitrate(){ unsigned bitrate = 0;  double packetDuration = this->packetDuration();  if (packetDuration > 0 && m_processedPacketsCount > 50) {  double averagePacketByteSize = m_processedPacketsSizeTotal / m_processedPacketsCount;  bitrate = 8 * averagePacketByteSize / packetDuration; }  return bitrate;}void Audio_Queue::handlePropertyChange(AudioFileStreamID inAudioFileStream, AudioFileStreamPropertyID inPropertyID, UInt32 *ioFlags){ OSStatus err = noErr;  AQ_TRACE("found property '%lu%lu%lu%lu'/n", (inPropertyID>>24)&255, (inPropertyID>>16)&255, (inPropertyID>>8)&255, inPropertyID&255);  switch (inPropertyID) {  case kAudioFileStreamProperty_ReadyToProducePackets:  {   cleanup();      // the file stream parser is now ready to produce audio packets.   // get the stream format.   memset(&m_streamDesc, 0, sizeof(m_streamDesc));   UInt32 asbdSize = sizeof(m_streamDesc);   err = AudioFileStreamGetProperty(inAudioFileStream, kAudioFileStreamProperty_DataFormat, &asbdSize, &m_streamDesc);   if (err) {    AQ_TRACE("%s: error in kAudioFileStreamProperty_DataFormat/n", __PRETTY_FUNCTION__);    m_lastError = err;    break;   }      // create the audio queue   err = AudioQueueNewOutput(&m_streamDesc, audioQueueOutputCallback, this, CFRunLoopGetCurrent(), NULL, 0, &m_outAQ);   if (err) {    AQ_TRACE("%s: error in AudioQueueNewOutput/n", __PRETTY_FUNCTION__);        if (m_delegate) {     m_delegate->audioQueueInitializationFailed();    }        m_lastError = err;    break;   }      // allocate audio queue buffers   for (unsigned int i = 0; i < AQ_BUFFERS; ++i) {    err = AudioQueueAllocateBuffer(m_outAQ, AQ_BUFSIZ, &m_audioQueueBuffer[i]);    if (err) {     /* If allocating the buffers failed, everything else will fail, too.      * Dispose the queue so that we can later on detect that this      * queue in fact has not been initialized.      */          AQ_TRACE("%s: error in AudioQueueAllocateBuffer/n", __PRETTY_FUNCTION__);          (void)AudioQueueDispose(m_outAQ, true);     m_outAQ = 0;          if (m_delegate) {      m_delegate->audioQueueInitializationFailed();     }          m_lastError = err;     break;    }   }      setCookiesForStream(inAudioFileStream);      // listen for kAudioQueueProperty_IsRunning   err = AudioQueueAddPropertyListener(m_outAQ, kAudioQueueProperty_IsRunning, audioQueueIsRunningCallback, this);   if (err) {    AQ_TRACE("%s: error in AudioQueueAddPropertyListener/n", __PRETTY_FUNCTION__);    m_lastError = err;    break;   }      break;  } }}void Audio_Queue::handleAudioPackets(UInt32 inNumberBytes, UInt32 inNumberPackets, const void *inInputData, AudioStreamPacketDescription *inPacketDescriptions){ if (!initialized()) {  AQ_TRACE("%s: warning: attempt to handle audio packets with uninitialized audio queue. return./n", __PRETTY_FUNCTION__);    return; }  // this is called by audio file stream when it finds packets of audio AQ_TRACE("got data. bytes: %lu packets: %lu/n", inNumberBytes, inNumberPackets);  /* Place each packet into a buffer and then send each buffer into the audio  queue */ UInt32 i;  if (!inPacketDescriptions) {  AQ_TRACE("%s: notice: supplying the packet descriptions for a supposed CBR data./n", __PRETTY_FUNCTION__);    // If no packet descriptions are supplied, assume we are dealing with CBR data  UInt32 base = inNumberBytes / inNumberPackets;  AudioStreamPacketDescription *descriptions = new AudioStreamPacketDescription[inNumberPackets];    for (i = 0; i < inNumberPackets; i++) {   descriptions[i].mStartOffset = (base * i);   descriptions[i].mDataByteSize = base;   descriptions[i].mVariableFramesInPacket = 0;  }  inPacketDescriptions = descriptions;    m_cbrPacketDescriptions.push_back(descriptions); }  for (i = 0; i < inNumberPackets && !m_waitingOnBuffer && m_queuedHead == NULL; i++) {  AudioStreamPacketDescription *desc = &inPacketDescriptions[i];  int ret = handlePacket((const char*)inInputData + desc->mStartOffset, desc);  if (!ret) break; } if (i == inNumberPackets) {  return; }  for (; i < inNumberPackets; i++) {  /* Allocate the packet */  UInt32 size = inPacketDescriptions[i].mDataByteSize;  queued_packet_t *packet = (queued_packet_t *)malloc(sizeof(queued_packet_t) + size);    /* Prepare the packet */  packet->next = NULL;  packet->desc = inPacketDescriptions[i];  packet->desc.mStartOffset = 0;  memcpy(packet->data, (const char *)inInputData + inPacketDescriptions[i].mStartOffset,    size);    if (m_queuedHead == NULL) {   m_queuedHead = m_queuedTail = packet;  } else {   m_queuedTail->next = packet;   m_queuedTail = packet;  } }} int Audio_Queue::handlePacket(const void *data, AudioStreamPacketDescription *desc){ if (!initialized()) {  AQ_TRACE("%s: warning: attempt to handle audio packets with uninitialized audio queue. return./n", __PRETTY_FUNCTION__);    return -1; }  AQ_TRACE("%s: enter/n", __PRETTY_FUNCTION__);  UInt32 packetSize = desc->mDataByteSize;  /* This shouldn't happen because most of the time we read the packet buffer  size from the file stream, but if we restored to guessing it we could  come up too small here */ if (packetSize > AQ_BUFSIZ) {  AQ_TRACE("%s: packetSize %lli > AQ_BUFSIZ %li/n", __PRETTY_FUNCTION__, packetSize, AQ_BUFSIZ);  return -1; }  // if the space remaining in the buffer is not enough for this packet, then // enqueue the buffer and wait for another to become available. if (AQ_BUFSIZ - m_bytesFilled < packetSize) {  int hasFreeBuffer = enqueueBuffer();  if (hasFreeBuffer <= 0) {   return hasFreeBuffer;  } } else {  AQ_TRACE("%s: skipped enqueueBuffer AQ_BUFSIZ - m_bytesFilled %lu, packetSize %lli/n", __PRETTY_FUNCTION__, (AQ_BUFSIZ - m_bytesFilled), packetSize); }  m_processedPacketsSizeTotal += packetSize; m_processedPacketsCount++;  // copy data to the audio queue buffer AudioQueueBufferRef buf = m_audioQueueBuffer[m_fillBufferIndex]; memcpy((char*)buf->mAudioData + m_bytesFilled, data, packetSize);  // fill out packet description to pass to enqueue() later on m_packetDescs[m_packetsFilled] = *desc; // Make sure the offset is relative to the start of the audio buffer m_packetDescs[m_packetsFilled].mStartOffset = m_bytesFilled; // keep track of bytes filled and packets filled m_bytesFilled += packetSize; m_packetsFilled++;  /* Maximum number of packets which can be contained in one buffer */#define kAQMaxPacketDescs 512  /* If filled our buffer with packets, then commit it to the system */ if (m_packetsFilled >= kAQMaxPacketDescs) {  return enqueueBuffer(); } return 1;}/* private */ void Audio_Queue::cleanup(){ if (!initialized()) {  AQ_TRACE("%s: warning: attempt to cleanup an uninitialized audio queue. return./n", __PRETTY_FUNCTION__);    return; }  if (AudioQueueDispose(m_outAQ, true) != 0) {  AQ_TRACE("%s: AudioQueueDispose failed!/n", __PRETTY_FUNCTION__); } m_outAQ = 0; m_fillBufferIndex = m_bytesFilled = m_packetsFilled = m_buffersUsed = m_processedPacketsSizeTotal = m_processedPacketsCount = 0;  for (size_t i=0; i < AQ_BUFFERS; i++) {  m_bufferInUse[i] = false; }  queued_packet_t *cur = m_queuedHead; while (cur) {  queued_packet_t *tmp = cur->next;  free(cur);  cur = tmp; } m_queuedHead = m_queuedHead = 0;  for (size_t i=0; i < m_cbrPacketDescriptions.size(); i++) {  delete[] m_cbrPacketDescriptions[i]; } m_cbrPacketDescriptions.clear();  m_waitingOnBuffer = false; m_lastError = noErr;} void Audio_Queue::setCookiesForStream(AudioFileStreamID inAudioFileStream){ OSStatus err;  // get the cookie size UInt32 cookieSize; Boolean writable;  err = AudioFileStreamGetPropertyInfo(inAudioFileStream, kAudioFileStreamProperty_MagicCookieData, &cookieSize, &writable); if (err) {  AQ_TRACE("error in info kAudioFileStreamProperty_MagicCookieData/n");  return; } AQ_TRACE("cookieSize %lu/n", cookieSize);  // get the cookie data void* cookieData = calloc(1, cookieSize); err = AudioFileStreamGetProperty(inAudioFileStream, kAudioFileStreamProperty_MagicCookieData, &cookieSize, cookieData); if (err) {  AQ_TRACE("error in get kAudioFileStreamProperty_MagicCookieData");  free(cookieData);  return; }  // set the cookie on the queue. err = AudioQueueSetProperty(m_outAQ, kAudioQueueProperty_MagicCookie, cookieData, cookieSize); free(cookieData); if (err) {  AQ_TRACE("error in set kAudioQueueProperty_MagicCookie"); }} void Audio_Queue::setState(State state){ if (m_state == state) {  /* We are already in this state! */  return; }  m_state = state;  if (m_delegate) {  m_delegate->audioQueueStateChanged(m_state); }}int Audio_Queue::enqueueBuffer(){ assert(!m_bufferInUse[m_fillBufferIndex]);  AQ_TRACE("%s: enter/n", __PRETTY_FUNCTION__);  m_bufferInUse[m_fillBufferIndex] = true; m_buffersUsed++;  // enqueue buffer AudioQueueBufferRef fillBuf = m_audioQueueBuffer[m_fillBufferIndex]; fillBuf->mAudioDataByteSize = m_bytesFilled;  assert(m_packetsFilled > 0); OSStatus err = AudioQueueEnqueueBuffer(m_outAQ, fillBuf, m_packetsFilled, m_packetDescs); if (!err) {  m_lastError = noErr;  start(); } else {  /* If we get an error here, it very likely means that the audio queue is no longer   running */  AQ_TRACE("%s: error in AudioQueueEnqueueBuffer/n", __PRETTY_FUNCTION__);  m_lastError = err;  return 1; }  // go to next buffer if (++m_fillBufferIndex >= AQ_BUFFERS) {  m_fillBufferIndex = 0;  } // reset bytes filled m_bytesFilled = 0; // reset packets filled m_packetsFilled = 0;  // wait until next buffer is not in use if (m_bufferInUse[m_fillBufferIndex]) {  AQ_TRACE("waiting for buffer %lu/n", m_fillBufferIndex);    if (m_delegate) {   m_delegate->audioQueueOverflow();  }  m_waitingOnBuffer = true;  return 0; }  return 1;} int Audio_Queue::findQueueBuffer(AudioQueueBufferRef inBuffer){ for (unsigned int i = 0; i < AQ_BUFFERS; ++i) {  if (inBuffer == m_audioQueueBuffer[i]) {   AQ_TRACE("findQueueBuffer %i/n", i);   return i;  } } return -1;} void Audio_Queue::enqueueCachedData(){ assert(!m_waitingOnBuffer); assert(!m_bufferInUse[m_fillBufferIndex]);  /* Queue up as many packets as possible into the buffers */ queued_packet_t *cur = m_queuedHead; while (cur) {  int ret = handlePacket(cur->data, &cur->desc);  if (ret == 0) {   break;   }  queued_packet_t *next = cur->next;  free(cur);  cur = next; } m_queuedHead = cur;  /* If we finished queueing all our saved packets, we can re-schedule the  * stream to run */ if (cur == NULL) {  m_queuedTail = NULL;  if (m_delegate) {   m_delegate->audioQueueUnderflow();  } }} // this is called by the audio queue when it has finished decoding our data. // The buffer is now free to be reused.void Audio_Queue::audioQueueOutputCallback(void *inClientData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer){ Audio_Queue *audioQueue = static_cast<Audio_Queue*>(inClientData);  unsigned int bufIndex = audioQueue->findQueueBuffer(inBuffer);  assert(audioQueue->m_bufferInUse[bufIndex]);  audioQueue->m_bufferInUse[bufIndex] = false; audioQueue->m_buffersUsed--;  if (audioQueue->m_buffersUsed == 0 && !audioQueue->m_queuedHead && audioQueue->m_delegate) {  audioQueue->m_delegate->audioQueueBuffersEmpty(); } else if (audioQueue->m_waitingOnBuffer) {  audioQueue->m_waitingOnBuffer = false;  audioQueue->enqueueCachedData(); }}void Audio_Queue::audioQueueIsRunningCallback(void *inClientData, AudioQueueRef inAQ, AudioQueuePropertyID inID){ Audio_Queue *audioQueue = static_cast<Audio_Queue*>(inClientData);  AQ_TRACE("%s: enter/n", __PRETTY_FUNCTION__);  UInt32 running; UInt32 output = sizeof(running); OSStatus err = AudioQueueGetProperty(inAQ, kAudioQueueProperty_IsRunning, &running, &output); if (err) {  AQ_TRACE("%s: error in kAudioQueueProperty_IsRunning/n", __PRETTY_FUNCTION__);  return; } if (running) {  AQ_TRACE("audio queue running!/n");  audioQueue->setState(RUNNING); } else {  audioQueue->setState(IDLE); }}  } // namespace astreamer

audio_stream.h

 

/* * This file is part of the FreeStreamer project, * (C)Copyright 2011-2013 Matias Muhonen. * See the file ''LICENSE'' for using the code. */#ifndef ASTREAMER_AUDIO_STREAM_H#define ASTREAMER_AUDIO_STREAM_H#import "http_stream.h"#include "audio_queue.h"#include <AudioToolbox/AudioToolbox.h>#include <string>namespace astreamer { enum Audio_Stream_Error { AS_ERR_OPEN = 1,   // Cannot open the audio stream AS_ERR_STREAM_PARSE = 2, // Parse error AS_ERR_NETWORK = 3  // Network error}; class Audio_Stream_Delegate; class Audio_Stream : public HTTP_Stream_Delegate, public Audio_Queue_Delegate { public: Audio_Stream_Delegate *m_delegate;  enum State {  STOPPED,  BUFFERING,  PLAYING,  SEEKING,  FAILED,  END_OF_FILE };  Audio_Stream(); virtual ~Audio_Stream();  void open(); void close(); void pause();  unsigned timePlayedInSeconds(); unsigned durationInSeconds(); void seekToTime(unsigned newSeekTime);  void setUrl(CFURLRef url); void setStrictContentTypeChecking(bool strictChecking); void setDefaultContentType(std::string& defaultContentType);  State state();  /* Audio_Queue_Delegate */ void audioQueueStateChanged(Audio_Queue::State state); void audioQueueBuffersEmpty(); void audioQueueOverflow(); void audioQueueUnderflow(); void audioQueueInitializationFailed();  /* HTTP_Stream_Delegate */ void streamIsReadyRead(); void streamHasBytesAvailable(UInt8 *data, UInt32 numBytes); void streamEndEncountered(); void streamErrorOccurred(); void streamMetaDataAvailable(std::map<CFStringRef,CFStringRef> metaData);private:  Audio_Stream(const Audio_Stream&); Audio_Stream& operator=(const Audio_Stream&);  bool m_httpStreamRunning; bool m_audioStreamParserRunning;  size_t m_contentLength;  State m_state; HTTP_Stream *m_httpStream; Audio_Queue *m_audioQueue;  AudioFileStreamID m_audioFileStream; // the audio file stream parser  SInt64 m_dataOffset; unsigned m_seekTime;  bool m_strictContentTypeChecking; std::string m_defaultContentType;  size_t contentLength(); void closeAndSignalError(int error); void setState(State state);  static void propertyValueCallback(void *inClientData, AudioFileStreamID inAudioFileStream, AudioFileStreamPropertyID inPropertyID, UInt32 *ioFlags); static void streamDataCallback(void *inClientData, UInt32 inNumberBytes, UInt32 inNumberPackets, const void *inInputData, AudioStreamPacketDescription *inPacketDescriptions);  AudioFileTypeID audioStreamTypeFromContentType(std::string contentType); }; class Audio_Stream_Delegate {public: virtual void audioStreamStateChanged(Audio_Stream::State state) = 0; virtual void audioStreamErrorOccurred(int errorCode) = 0; virtual void audioStreamMetaDataAvailable(std::map<CFStringRef,CFStringRef> metaData) = 0;}; } // namespace astreamer#endif // ASTREAMER_AUDIO_STREAM_H

更多源碼請點擊下載:iOS音樂播放器實現代碼

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到IOS開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日本免费一区二区三区视频观看| 黑人极品videos精品欧美裸| 在线视频精品一| 亚洲美腿欧美激情另类| 992tv在线成人免费观看| 亚洲xxxx做受欧美| 2025国产精品视频| 欧美成在线视频| 国产精品亚洲片夜色在线| 91成人福利在线| 在线观看国产欧美| 韩国美女主播一区| 欧美日韩午夜激情| 亚洲精品国产美女| 欧美激情网友自拍| 国产网站欧美日韩免费精品在线观看| 国产主播欧美精品| 亚洲精品一区二区在线| 欧美日韩aaaa| 91人人爽人人爽人人精88v| 欧美性猛交xxxx乱大交极品| 日韩精品在线视频观看| 亚洲欧美日韩久久久久久| 精品无人区太爽高潮在线播放| 亚洲成年人影院在线| 亚洲成人激情视频| 欧美日韩国产中文精品字幕自在自线| 欧美激情第三页| 性欧美在线看片a免费观看| 国产婷婷色综合av蜜臀av| 国内精品小视频| 精品国产一区二区在线| 91爱视频在线| 日韩一区二区精品视频| 久久这里只有精品视频首页| 亚洲一区二区三区成人在线视频精品| 中文字幕亚洲色图| 日韩中文字幕久久| 97国产精品视频| 欧美专区国产专区| 久久精品一区中文字幕| 亚洲iv一区二区三区| 亚洲美女www午夜| 久久偷看各类女兵18女厕嘘嘘| 国产成+人+综合+亚洲欧美丁香花| 91伊人影院在线播放| 久久久久久久久久国产| 国产视频久久久久久久| 日韩中文字幕在线视频| 日本精品免费观看| 国产精品视频一区二区三区四| 久久视频在线免费观看| 欧美日韩国产精品专区| 日韩免费在线观看视频| 亚洲色图美腿丝袜| 日韩激情av在线免费观看| 国产一区二区三区四区福利| 国产精品激情自拍| 国产成人精品一区二区三区| 欧美孕妇性xx| 日韩欧美国产免费播放| 538国产精品一区二区免费视频| 亚洲福利视频二区| 亚洲剧情一区二区| 国产精品亚洲综合天堂夜夜| 国产精品极品尤物在线观看| 日韩免费看的电影电视剧大全| 亚洲欧美日韩国产中文专区| 欧美—级a级欧美特级ar全黄| 日韩欧美在线播放| 91国偷自产一区二区三区的观看方式| 国产精品久久久久久久app| 欧洲亚洲免费在线| 亚洲欧美综合图区| 91久久精品视频| 91网站免费观看| 国产91精品不卡视频| 亚洲欧洲在线播放| 亚洲第一级黄色片| 精品亚洲国产成av人片传媒| 91久久久国产精品| 国产精品久久久久久一区二区| 57pao成人国产永久免费| 国产精品99久久久久久久久| 在线播放亚洲激情| 欧美日韩国产综合视频在线观看中文| 日韩av中文在线| 精品性高朝久久久久久久| 欧美成年人在线观看| 欧美整片在线观看| www.久久草.com| 国产精品久久久| 91精品综合久久久久久五月天| 伊人激情综合网| 日日摸夜夜添一区| 5566日本婷婷色中文字幕97| 欧美日韩国产激情| 亚洲精品国产拍免费91在线| 中文字幕日韩欧美在线| 日韩有码片在线观看| 久久久久亚洲精品| 亚洲第一福利在线观看| 欧美高清视频一区二区| 国产精品夫妻激情| 国产大片精品免费永久看nba| 色偷偷av亚洲男人的天堂| 久久久久亚洲精品| 欧美日韩性视频| 国产亚洲美女精品久久久| 一本大道久久加勒比香蕉| 国产精品综合久久久| 久久精品视频在线观看| 中文字幕v亚洲ⅴv天堂| 欧美精品福利在线| 欧美精品在线免费播放| 欧美在线观看视频| 国产又爽又黄的激情精品视频| 久久视频中文字幕| 国产亚洲成精品久久| 成人午夜激情免费视频| 成人黄色午夜影院| 97精品视频在线| 中文字幕日韩欧美在线| 国产精品美女网站| 亚洲国产高潮在线观看| 九九热99久久久国产盗摄| 欧洲精品毛片网站| 亚洲成av人影院在线观看| 日韩精品中文字幕久久臀| 黑人巨大精品欧美一区二区三区| 日韩成人小视频| 97人人模人人爽人人喊中文字| 青青久久av北条麻妃海外网| 精品国产一区二区在线| 茄子视频成人在线| 一本大道亚洲视频| 中文字幕日韩综合av| 日韩视频在线免费| 亚洲成人精品久久| 久久久av网站| 精品久久久中文| 国产成人拍精品视频午夜网站| 欧美成人性生活| 欧美精品成人91久久久久久久| 日韩免费中文字幕| 中文字幕欧美日韩| 亚洲精品视频在线观看视频| 欧美性理论片在线观看片免费| 亚洲成人教育av| 久久在线免费观看视频| 中文字幕精品www乱入免费视频| 国产精品一区二区久久国产| 久久久女人电视剧免费播放下载| 国产美女精品视频| 欧美日韩免费网站| 成人欧美一区二区三区在线湿哒哒| 亚洲成人精品久久| 日韩在线观看你懂的| 国产精品视频999| 日本在线观看天堂男亚洲| 一区二区三区无码高清视频| 日韩激情片免费| 亚洲午夜精品视频| 中文字幕亚洲综合久久筱田步美|