亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        簡(jiǎn)析Android語(yǔ)音助手開發(fā)的一種實(shí)現(xiàn)方案

        2020-04-01 18:12:58馮揚(yáng)駱德漢
        現(xiàn)代計(jì)算機(jī) 2020年6期
        關(guān)鍵詞:指令方法

        馮揚(yáng),駱德漢

        (廣東工業(yè)大學(xué)信息工程學(xué)院,廣州510006)

        0 引言

        語(yǔ)音助手是人工智能應(yīng)用的重要形式。Siri(蘋果智能語(yǔ)音助手)帶動(dòng)了業(yè)內(nèi)人工智能語(yǔ)音的發(fā)展。從載體來(lái)看,目前語(yǔ)音助手主要分為三大類:以Siri為代表的手機(jī)輔助功能,以天貓精靈、小度音箱為代表的智能音箱以及以榮耀智慧屏為代表的大屏語(yǔ)音交互,其中手機(jī)是智能語(yǔ)音助手的主要戰(zhàn)場(chǎng)。

        首先,語(yǔ)音交互取消了屏幕的限制,除了作為家庭的控制中樞,語(yǔ)音交互在可穿戴設(shè)備以及輔助駕駛領(lǐng)域也有著十分可觀的應(yīng)用前景。就輔助駕駛來(lái)說(shuō),由于駕駛員需要注意力的高度集中,需要在不干擾視野的情況下僅通過聲音就可以滿足交互的需求,例如搜索詢問道路、編寫短信、撥打電話、尋找食譜或查看天氣等。

        1 關(guān)鍵技術(shù)

        本文旨在分析語(yǔ)音助手設(shè)計(jì)開發(fā)所用到的關(guān)鍵技術(shù),自設(shè)計(jì)一款安卓語(yǔ)音助手App,實(shí)現(xiàn)的基礎(chǔ)功能包括打電話、發(fā)短信、播放音樂/視頻、打開應(yīng)用等,還添加了個(gè)性化的互聯(lián)網(wǎng)服務(wù)功能包括中英翻譯、電影搜索等。在設(shè)計(jì)開發(fā)過程中,集成使用了科大訊飛SDK(語(yǔ)音聽寫和語(yǔ)音合成)、百度地圖定位SDK,以及主流網(wǎng)絡(luò)請(qǐng)求框架Retrofit和JSON數(shù)據(jù)解析等關(guān)鍵技術(shù)。整個(gè)使用流程如圖1所示。

        圖1 語(yǔ)音助手流程圖

        1.1 語(yǔ)音交互

        實(shí)現(xiàn)語(yǔ)音交互功能需要用到第三方工具庫(kù),該流程如下所示:

        (1)下載科大訊飛語(yǔ)音開發(fā)SDK(含語(yǔ)音聽寫和語(yǔ)音合成功能),分別將libmsc.so、Msc.jar和Sunflower.jar以及assets文件夾等導(dǎo)入到Android項(xiàng)目中,并在An?droidManifest.xml文件中申請(qǐng)相關(guān)權(quán)限。

        (2)使用注冊(cè)時(shí)申請(qǐng)的APPID初始化語(yǔ)音配置對(duì)象。代碼如下所示:

        SpeechUtility.createUtility(context,SpeechConstant.AP?PID+"=1234ABCD");

        (3)分別創(chuàng)建語(yǔ)音聽寫和語(yǔ)音合成的監(jiān)聽器對(duì)象。代碼如下所示:

        SpeechRecognizer mSRec=SpeechRecognizer.creat?eRecognizer(context,mInitListener);

        SpeechSynthesizer mTts=SpeechSynthesizer.create?Synthesizer(context,TtsInitListener);

        (4)監(jiān)聽“開始講話”按鈕是否按下,獲取音頻數(shù)據(jù)返回SDK進(jìn)行處理,進(jìn)行音頻轉(zhuǎn)文字過程(即語(yǔ)音聽寫)。代碼如下所示:

        @Override

        public void onClick(Viewview){

        if(null==mSRec||null==mTts){ //創(chuàng)建對(duì)象失敗后的操作

        return;

        }

        switch(view.getId()){

        case R.id.mSRec_start:{

        int ret=mSRec.startListening(mRecognizerListener);

        if(ret!=ErrorCode.SUCCESS){//聽寫失敗后進(jìn)行的操作 }

        else{ //聽寫成功后進(jìn)行的操作 }

        }break;

        }

        }

        首先判斷語(yǔ)音聽寫對(duì)象mSRec和語(yǔ)音合成對(duì)象mTts是否成功創(chuàng)建,然后通過調(diào)用mSRec.startListen?ing()方法,監(jiān)聽語(yǔ)音聽寫過程中的狀態(tài)返回碼來(lái)進(jìn)行判斷是否存在異常。

        (5)RecognizerListener接口實(shí)現(xiàn)了語(yǔ)音聽寫結(jié)果的數(shù)據(jù)解析及可視化,存儲(chǔ)到字符串keywords中。代碼如下所示:

        RecognizerListener mRecognizerListener=new RecognizerLis?tener(){

        @Override

        public void onBeginOfSpeech(){//語(yǔ)音開始后的操作}

        @Override public void onError(SpeechError error){//語(yǔ)音出錯(cuò)后的操作}

        @Override public void onEndOfSpeech(){//語(yǔ)音結(jié)束后的操作}

        @Override

        public void onResult(RecognizerResult results,boolean is?Last){

        //解析語(yǔ)音聽寫結(jié)果數(shù)據(jù)

        }

        }

        1.2 JSON數(shù)據(jù)解析

        JSON的全稱是JavaScript Object Notation,它是一種代碼輕量級(jí)的數(shù)據(jù)交互格式,方便人們閱讀和編寫以及機(jī)器進(jìn)行生成和解析。在實(shí)際應(yīng)用中,JSON主要有兩種表示結(jié)構(gòu):對(duì)象和數(shù)組[1]。這里以JSON對(duì)象為例,結(jié)合音頻數(shù)據(jù)處理結(jié)果數(shù)據(jù)JSON格式的解析代碼,分析JSON數(shù)據(jù)解析方法。代碼如下所示:

        HashMap<String,String>map=new LinkedHashMap<>();

        String text=JsonParser.parseIatResult(results.getResultString

        ());

        JSONObject resultJson=new JSONObject(results.getResult?

        String());

        Stringsn=resultJson.optString("sn");

        map.put(sn,text);

        StringBuffer resultBuffer=new StringBuffer();

        for(Stringkey:map.keySet()){

        resultBuffer.append(map.get(key));

        }

        Stringkeywords=resultBuffer.toString();

        mSRecResults.setText(keywords);

        其中第三行代碼通過new JSONObject(Stringjson)創(chuàng)建一個(gè)JSONObject對(duì)象,第四行使用optString(String key)方法獲取該對(duì)象鍵值對(duì)“key:value”中的String類型value值。同理可得,獲取其他基本數(shù)據(jù)類型鍵值對(duì)的方法也與之相似,如optInt(Stringkey)、opt?Long(String key)分別返回long型和int型的值[1]。

        1.3 語(yǔ)音合成

        結(jié)合科大訊飛SDK實(shí)現(xiàn)語(yǔ)音合成功能,按1.1小節(jié)中的步驟配置好資源文件后,使用setParam()方法設(shè)定默認(rèn)發(fā)音人、音量、語(yǔ)調(diào)、語(yǔ)速等參數(shù),然后使用mTts.startSpeaking(strings,mTtsListener)就 可 以 將strings源字符串以音頻形式輸出,同時(shí)返回code狀態(tài)碼判斷是否存在異常。

        代碼如下所示:

        public static void setParam(){

        mTts.setParameter(SpeechConstant.SPEED,mSharedPrefer?ences.getString("speed_preference","50"));

        }int code=mTts.startSpeaking("歡迎使用車載語(yǔ)音助手",mTtsListener);

        1.4 地圖定位

        實(shí)現(xiàn)定位導(dǎo)航功能需要用到第三方工具庫(kù),該流程如下所示:

        (1)下載百度地圖Android SDK(含基礎(chǔ)定位和導(dǎo)航功能),分別將libs文件夾、assets文件夾和Baid?uLBS_Android.jar導(dǎo)入到項(xiàng)目中,申請(qǐng)定位相關(guān)權(quán)限。

        (2)獲取系統(tǒng)定位服務(wù),注冊(cè)監(jiān)聽并開啟定位服務(wù)。代碼如下所示:

        LocationService locService=getApplication().locationService;

        locService.registerListener(mListener);

        locService.start();

        (3)其中,服務(wù)監(jiān)聽器mListener的定義代碼如下所示:

        BDAbstractLocationListener mListener=new BDAbstractLoca?tionListener(){

        @Override

        public void onReceiveLocation(BDLocation location){

        if(null!=location&&location.getLocType()!=Location.

        TypeServerError){//獲取相關(guān)地理信息

        }}};

        抽象監(jiān)聽接口BDAbstractLocationListener主要用于定位,通過各種getXX()方法來(lái)獲取地理位置信息。這里首先判斷BDLocation對(duì)象及LocationService服務(wù)是否正常,然后分別使用location.getAddrStr()、getLati?tude()等方法獲取地址信息、經(jīng)緯度信息等。

        2 實(shí)例

        在結(jié)合語(yǔ)音SDK和地圖SDK的基礎(chǔ)上,嵌入使用Retrofit框架和JSON解析等方法,來(lái)設(shè)計(jì)實(shí)現(xiàn)一款語(yǔ)音助手軟件,剖析其開發(fā)的過程。使用過程中主要是根據(jù)語(yǔ)音聽寫結(jié)果中的命令關(guān)鍵詞進(jìn)行判斷,實(shí)現(xiàn)不同事件的跳轉(zhuǎn)處理,以及使用語(yǔ)音合成來(lái)完成人機(jī)之間的語(yǔ)音交互功能。

        2.1 指令判斷:打開應(yīng)用

        先檢查讀取手機(jī)應(yīng)用信息的權(quán)限,使用queryIn?tentActivities()方法遍歷已安裝的所有應(yīng)用,同時(shí)分別通過ResolveInfo.activityInfo.packageName獲取應(yīng)用包名稱、ResolveInfo.activityInfo.loadLabel(getPackageMan?ager())獲取應(yīng)用名稱。結(jié)合startActivity(package?Name)方法就可以實(shí)現(xiàn)打開應(yīng)用的操作。代碼如下所示:

        (1)讀取所有應(yīng)用信息,用List列表存儲(chǔ)

        List<ResolveInfo>applist=getPackageManager()

        .queryIntentActivities(queryIntent,0);

        (2)判斷聽寫結(jié)果中如有“打開XX應(yīng)用”指令,則打開該應(yīng)用

        if(keywords.contains(appName)&&keywords.contains(“打開應(yīng)用”))

        startActivity(packageManager.getLaunchIntentForPackage(packageName));

        2.2 指令判斷:打電話

        先檢查讀取聯(lián)系人、打電話的權(quán)限,分別使用兩組ArrayList來(lái)存儲(chǔ)聯(lián)系人名稱和聯(lián)系人號(hào)碼。根據(jù)語(yǔ)音聽寫結(jié)果的指令判斷,撥打特定聯(lián)系人的號(hào)碼。其中設(shè)定android.intent.action.CALL進(jìn)行撥打電話的Activi?ty模式,呼叫指定號(hào)碼的數(shù)據(jù)格式為:tel:+phone num?ber。代碼如下所示:

        (1)讀取聯(lián)系人信息

        List<String>namelist=new ArrayList<>();

        List<String>numList=new ArrayList<>();

        Cursor cursor=getContentResolver().query(ContactsContract

        .CommonDataKinds.Phone.CONTENT_URI,null,null,null,

        null);

        if(cursor!=null){

        while(cursor.moveToNext()){//分別讀取名字和號(hào)碼存儲(chǔ)到對(duì)應(yīng)的List}cursor.close();}

        (2)根據(jù)語(yǔ)音指令,給特定聯(lián)系人撥打電話

        for(int j=0;j<namelist.size();j++){

        String s=namelist.get(j);if(keywords.contains(s)&&keywords.contains("打電話")){

        Intent intent=new Intent(Intent.ACTION_CALL);

        Uridata=Uri.parse("tel:"+numList.get(j));

        intent.setData(data);

        startActivity(intent);

        }

        2.3 指令判斷:發(fā)短信

        先檢查發(fā)送短信的權(quán)限,而獲取聯(lián)系人信息的過程與2.2小節(jié)的第(1)點(diǎn)相同。根據(jù)語(yǔ)音聽寫結(jié)果的指令判斷,給特定聯(lián)系人發(fā)送短信,并指定輸入框的語(yǔ)音短信內(nèi)容。代碼如下所示:

        for(int j=0;j<namelist.size();j++){

        String s=namelist.get(j);

        if(keywords.contains(s)&&keywords.contains("發(fā) 短 信

        ")){

        Intent sendIntent=new Intent(Intent.ACTION_SENDTO);

        sendIntent.setData(Uri.parse("smsto:"+numList.get(j)));

        sendIntent.putExtra("sms_body","【語(yǔ)音短信】:"+key?

        words);

        startActivity(sendIntent);

        }

        }

        2.4 指令判斷:中英翻譯

        這里使用網(wǎng)絡(luò)請(qǐng)求框架Retrofit,將語(yǔ)音聽寫結(jié)果中需要翻譯的部分內(nèi)容上傳到有道翻譯服務(wù)器進(jìn)行翻譯以后,根據(jù)有道翻譯API的返回?cái)?shù)據(jù)格式,輸出翻譯結(jié)果。具體流程如下所示:

        (1)創(chuàng)建一個(gè)Retrofit對(duì)象,并實(shí)例化。核心代碼:

        Retrofit retrofit=new Retrofit.Builder().baseUrl("https://fanyi.youdao.com/")

        .addConverterFactory(GsonConverterFactory.create()).build();

        (2)定義接口trans_Interface,使用post請(qǐng)求方式,定義url尾址,完整地址就是baseUrl+尾址。核心代碼:

        public interface trans_Interface{

        @POST("translate?doctype=json&jsonversion=&type=&key?from=&model=&mid=&imei=&vendor=&screen=&ssid=&net ?work=&abtest=")

        @FormUrlEncoded

        Call<Translation1>getCall(@Field("i")String targetSen?tence);

        }

        (3)用retrofit創(chuàng)建接口實(shí)例trans_Interface,并調(diào)用接口方法進(jìn)行網(wǎng)絡(luò)請(qǐng)求。核心代碼:

        trans_Interface request=retrofit.create(trans_Interface.clas);

        Call<Translation1>call= request.getCall(keywords);

        call.enqueue(new Callback<Translation1>(){

        @Override

        public void onResponse(Call<Translation1>call,Response

        <Translation1>response){//打印翻譯結(jié)果

        Log.d(response.body().getTranslateResult().get(0).get(0) .getTgt());}

        @Override

        public void onFailure(Call<Translation1>call,Throwable throwable){

        //翻譯出錯(cuò)后的處理

        }

        });

        2.5 指令判斷:搜索電影

        依然使用網(wǎng)絡(luò)請(qǐng)求框架Retrofit,判斷電影搜索的語(yǔ)音命令,訪問豆瓣電影服務(wù)器,根據(jù)豆瓣電影API返回Top30的電影數(shù)據(jù),然后解析JSON格式數(shù)據(jù)進(jìn)行顯示得以實(shí)現(xiàn)。具體流程如下所示:

        (1)創(chuàng)建Retrofit對(duì)象,并實(shí)例化。核心代碼:

        Retrofit mRetrofit=new Retrofit.Builder()

        .addConverterFactory(GsonConverterFactory.create())

        .baseUrl("https://api.douban.com/v2/movie/").build();

        (2)定義接口MovieService,使用get請(qǐng)求方式,定義url尾址。核心代碼:

        public interface MovieService{

        @GET

        ("top30?apikey=0b2bdeda43b5688921839c8ecb20399b")

        Observable<MovieSubject>getTop30(

        @Query("start")int start,

        @Query("count")int count);

        }

        (3)用mRetrofit創(chuàng)建接口實(shí)例MovieService,并調(diào)用接口方法進(jìn)行網(wǎng)絡(luò)請(qǐng)求。核心代碼:

        MovieService movieService=mRetrofit.create(MovieService.

        class);

        Call<MovieSubject>call=movieService.getTop30(0,30);

        call.enqueue(new Callback<MovieSubject>(){

        @Override

        public void onResponse(Call<MovieSubject>call,Response<MovieSubject>response){

        //獲取response響應(yīng)對(duì)象中的top30電影數(shù)據(jù)(中英文名稱

        、主演、導(dǎo)演、年份等)并顯示

        }

        @Override

        public void onFailure(Call<MovieSubject>call,Throwable t){

        //電影數(shù)據(jù)獲取失敗后的操作

        }});

        2.6 指令判斷:媒體播放

        (1)視頻播放

        Android在播放音頻和視頻方面做了不錯(cuò)的支持,它提供了一套較為完整的API,使得開發(fā)者可以輕松編寫出一個(gè)簡(jiǎn)易的音頻或視頻播放器[2]。這里額外加入了語(yǔ)音識(shí)別控制功能,通過語(yǔ)音輸入來(lái)實(shí)現(xiàn)本地媒體(音樂和視頻)的播放、暫停、停止、切換以及音量大小調(diào)節(jié)等操作。這里以本地存儲(chǔ)5首音頻和2個(gè)視頻為例,初始化VideoPlayer(),核心代碼:

        ①播放視頻文件主要通過VideoView類來(lái)實(shí)現(xiàn),這個(gè)類集視頻的顯示和控制于一身[2]。調(diào)用initVideo?Player()來(lái)設(shè)置視頻文件在SD卡中的存儲(chǔ)路徑。進(jìn)一步在setVideoURI(Uri.parse(path))解析為通用資源標(biāo)志符Uri并獲取數(shù)據(jù)。其實(shí)際背后是使用MediaPlayer工具類來(lái)對(duì)視頻文件進(jìn)行操作的。

        private void initVideoPlayer(){

        if(videoNum>2) videoNum=0;

        VideoView videoView= findViewById (R.id.vid?eoView);

        File file=new File(Environment.getExternalStorageDirec?tory(),

        videos[videoNum++]);

        videoView.setVideoPath(file.getPath());

        videoView.setMediaController(new android.widget.Media?Controller(this));}

        (2)然后根據(jù)語(yǔ)音聽寫命令來(lái)進(jìn)行視頻文件的播放、暫停、切換等操作。核心代碼:

        if(keywords.contains("視頻")){

        videoView.setVisibility(View.VISIBLE);

        if(keywords.contains("播放")){

        if(!videoView.isPlaying())

        videoView.start();

        }else if(keywords.contains("暫停")){

        if(videoView.isPlaying())

        videoView.pause();

        }else if(keywords.contains("重播")){

        if(videoView.isPlaying()) videoView.resume();

        }else if(keywords.contains("下一個(gè)")){

        if(videoView.isPlaying())

        videoView.stopPlayback();

        initVideoPlayer();

        videoView.start();

        }

        }

        (2)音樂播放

        同理,創(chuàng)建一個(gè)MediaPlayer對(duì)象,調(diào)用setData?Source()方法來(lái)設(shè)置音頻文件的路徑,再調(diào)用prepare()方法進(jìn)入到準(zhǔn)備狀態(tài)[2]。最后通過語(yǔ)音輸入指令,調(diào)用start()方法就可以進(jìn)行播放等操作。核心代碼如下:

        (1)通過獲取path轉(zhuǎn)換Uri并獲取數(shù)據(jù)。

        privatevoid initMediaPlayer(){

        if(musicNum>5) musicNum=0;

        File file=new File(Environment.getExternalStorageDirectory(),musics[musicNum++]);

        mediaPlayer.setDataSource(file.getPath());

        mediaPlayer.prepare();

        }

        (2)根據(jù)語(yǔ)音聽寫命令來(lái)進(jìn)行音樂文件的播放、暫停等操作。核心代碼:

        if(keywords.contains("音樂")){

        if(keywords.contains("播放")){

        if(!mediaPlayer.isPlaying())

        mediaPlayer.start();

        }elseif(keywords.contains("暫停")){

        if(mediaPlayer.isPlaying())

        mediaPlayer.pause();

        }elseif(keywords.contains("停止")){

        if(mediaPlayer.isPlaying()){

        mediaPlayer.reset();

        mediaPlayer.release();

        }

        }else if(keywords.contains("下一首")){

        if(videoView.isPlaying()){

        mediaPlayer.reset();

        mediaPlayer.release();

        }initMediaPlayer();

        mediaPlayer.start();

        }

        }

        (3)音量調(diào)節(jié)

        通過AudioManager類來(lái)控制手機(jī)音頻調(diào)節(jié),首先獲取當(dāng)前媒體音量大小,然后根據(jù)語(yǔ)音指令進(jìn)行音量增減調(diào)節(jié)的操作。具體代碼如下所示:

        AudioManager audioManager=getApplicationContext()

        .getSystemService(Context.AUDIO_SERVICE);

        int currentVolume =audioManager.getStreamVolume(Audio?

        Manager.STREAM_MUSIC);

        int maxVolume=audioManager.getStreamMaxVolume(Audio?

        Manager.STREAM_MUSIC);

        int minVolume=audioManager.getStreamMinVolume(Audio?

        Manager.STREAM_MUSIC);

        if(keywords.contains("調(diào)大音量")){

        if(currentVolume<maxVolume)

        audioManager.setStreamVolume(

        AudioManager.STREAM_MUSIC,currentVolume++,Au?

        dioManager.FLAG_PLAY_SOUND);

        }else showTip("音量已經(jīng)調(diào)到最大");

        if(keywords.contains("調(diào)小音量")){

        if(currentVolume>minVolume)

        audioManager.setStreamVolume(

        AudioManager.STREAM_MUSIC,currentVolume--,Au?

        dioManager.FLAG_PLAY_SOUND);

        }else showTip("已經(jīng)調(diào)到靜音");

        2.7 結(jié)果顯示

        整個(gè)程序的運(yùn)行結(jié)果如圖2所示。

        圖2 程序運(yùn)行結(jié)果

        3 結(jié)語(yǔ)

        經(jīng)過測(cè)試和程序運(yùn)行結(jié)果可以看出,整個(gè)實(shí)現(xiàn)方案是完全可行的。上述的這種語(yǔ)音助手實(shí)現(xiàn)方案,不僅能夠應(yīng)用在可穿戴設(shè)備方面,還能拓展到輔助駕駛領(lǐng)域。其中Retrofit框架作為當(dāng)前Android網(wǎng)絡(luò)請(qǐng)求非常流行的方式,結(jié)合JSON數(shù)據(jù)解析能夠進(jìn)一步實(shí)現(xiàn)查詢天氣、搜索附近景點(diǎn)/美食等操作,具有很快速實(shí)現(xiàn)、簡(jiǎn)化代碼的優(yōu)點(diǎn)??偟膩?lái)說(shuō),這種語(yǔ)音助手實(shí)現(xiàn)方案還是具有卓越的可擴(kuò)展性的。

        猜你喜歡
        指令方法
        聽我指令:大催眠術(shù)
        學(xué)習(xí)方法
        ARINC661顯控指令快速驗(yàn)證方法
        LED照明產(chǎn)品歐盟ErP指令要求解讀
        可能是方法不對(duì)
        殺毒軟件中指令虛擬機(jī)的脆弱性分析
        用對(duì)方法才能瘦
        Coco薇(2016年2期)2016-03-22 02:42:52
        四大方法 教你不再“坐以待病”!
        Coco薇(2015年1期)2015-08-13 02:47:34
        賺錢方法
        捕魚
        男女性生活视频免费网站| 无码精品国产va在线观看| 91精品福利一区二区| 无码流畅无码福利午夜| 国产三级av大全在线爽| 午夜天堂精品久久久久| 亚洲色无码播放| 国产成人香蕉久久久久| 高清国产亚洲精品自在久久| 国产精品麻豆va在线播放| 亚洲乱亚洲乱少妇无码99p | 亚洲熟女av中文字幕网站| 高潮av一区二区三区| 免费av一区二区三区| 国产精品美女久久久久| 亚洲嫩模高清在线视频| 日韩av中文字幕波多野九色| 伊人大杳焦在线| 无尽动漫性视频╳╳╳3d| 草莓视频在线观看无码免费| 91久久精品一区二区| 久热re这里精品视频在线6| 国产精品午睡沙发系列| 免费在线观看蜜桃视频| 亚洲伊人av天堂有码在线| 色一情一乱一伦| 中国精品久久精品三级| 日本骚色老妇视频网站| 美腿丝袜诱惑一区二区| 人妻av无码系列一区二区三区| 亚洲a级片在线观看| 九九久久精品一区二区三区av| 亚洲精品天堂在线观看| 玖玖资源站亚洲最大的网站| 女人和拘做受全程看视频| 亚洲色图在线观看视频| 中文在线最新版天堂av| 精品无人区无码乱码毛片国产| 亚洲精品国产成人| 国产呦系列视频网站在线观看| 黄色一区二区三区大全观看|