华为智慧屏的分布式语音音乐软件,看到就可以说话在HarmonyOS的官方文档中,有这么一个只能在智慧屏上使用的功能,也就是可以说是它是可见的。就在很久以前,我参考官方发布的音乐播放器定制了一个自己的播放器。今天,我把它改造成了一个智慧屏应用,并增加了看和说的功能。坐等真机演示,有设备的朋友可以测试一下!1.各设备效果演示,手机平板,智慧屏要在真机上测试...(7月7日做)2.视听功能根据官方介绍document,seeingandsaying就是将一些热词关联到Component上,来监听语音热词,进行一些相应的操作。比如在浏览图片时,说出图片的名称或者角标的序号,从而实现打开图片的效果。相应的,我们可以将分布式音乐播放器改造成语音控制,比如将“播放”、“暂停”、“上一首”等热词绑定到相应的组件上,当检测到热词时,执行该功能即可。三、所见即所得1、热词注册创建一个Component.VoiceEvent对象,并设置对应的热词,英文和中文均可。能看能说的功能核心是Component.VoiceEvent对象,一个对象对应一个事件。//例如设置播放事件Component.VoiceEventeventplay=newComponent.VoiceEvent("play");一个Component.VoiceEvent对象可以绑定多个热词。eventplay.addSynonyms("播放");绑定热词后,哪个组件需要这个语音事件,就需要注册哪个组件。//比如分布式音乐播放器中的播放按钮注册语音事件。musicPlayButton.subscribeVoiceEvents(事件播放);如果组件有多个语音事件要响应,我们将创建多个Component.VoiceEvent对象并将它们全部注册。一个对象对应一个事件。2.事件开发前面我们设置了语音事件,注册了一个播放按钮。但这只是注册,然后呢?然后就没有了,因为我们还没有开发事件,按钮应该在事件发生时响应。(1)实现SpeechEventListener接口privateComponent.SpeechEventListenerspeechEventListener=newComponent.SpeechEventListener(){@OverridepublicbooleanonSpeechEvent(Componentv,SpeechEventevent){if(event.getActionProperty().equals("play")){...//检测注册的热词并进行相应处理playOrpause();}返回假;};}(2)通过setSpeechEventListener方法实现回调注册musicplayButton.setSpeechEventListener(speechEventListener);已经明白了,那么下面是分布式音乐播放器改造案例,有兴趣的读者往下看。四、案例编写1.项目结构2.UI设计3.架构简要分析这里对架构进行简要分析,详见附件项目文档。PlayerManager.java封装播放器类,设置音乐路径,播放暂停,上一曲和下一曲功能。/***先播放前准备媒体资源*/publicvoidprepareMusic(){...}/***准备音频路径和准备媒体资源*@paramUri*/publicvoidsetResource(StringUri){...}/***播放*/publicvoidplay(){...}/***暂停*/publicvoidpause(){...}/***定时事件通知更新进度条*DELAY_TIME延迟1s*PERIOD两个事件间隔1s*/privatevoidstartTimetask(){...}//...StateListener播放器状态监听接口,监听播放器状态然后进行一些事件通知。包com.yzj.musicplayer.Player;publicinterfaceStateListener{voidonPlaySuccess(inttotalTime);无效onPauseSuccess();voidonPositionChange(intcurrentTime);voidonMusicFinished();voidonUriSet(字符串名称);生成一个对话框以显示可以分发和传输的设备列表。我不会详细介绍它。用JAVA做UI体验不是很好。MainAbilitySlice主页面4.绑定可见,事件可说。这里我们有播放、暂停、上一曲、下一曲、拖动进度条、分布式传输等操作。我们给他们一个一个添加语音事件。//测试//播放privateComponent.VoiceEventeventplay;//暂停privateComponent.VoiceEventeventpause;//下一个privateComponent.VoiceEventeventnext;//previousprivateComponent.VoiceEventeventpre;//流privateComponent.VoiceEventeventremote;//流声对应事件privateComponent.SpeechEventListenerspeech_mShowDeviceListListener=newComponent.SpeechEventListener(){@OverridepublicbooleanonSpeechEvent(Componentcomponent,SpeechEventspeechEvent){if("speechEvent.getActionquaperty"Property)("flow){//显示流selecteddevicelistcontinuationRegisterManager.showDeviceList(abilityToken,null,null);}returnfalse;}};voidinitview(){//绑定热词eventplay=newComponent.VoiceEvent("play");eventpause=newComponent.VoiceEvent("暂停");eventnext=newComponent.VoiceEvent("下一首歌曲");eventpre=newComponent.VoiceEvent("上一首歌曲");eventremote=newComponent.VoiceEvent("流");//为播放按钮注册热词musicPlayButton.subscribeVoiceEvents(eventplay);musicPlayButton.subscribeVoiceEvents(事件暂停);//设置播放按钮的响应事件musicPlayButton.setSpeechEventListener(newComponent.SpeechEventListener(){@OverridepublicbooleanonSpeechEvent(Componentcomponent,SpeechEventspeechEvent){if(speechEvent.getActionProperty().equals("Playing")){if(playerManager.isPlaying()){Log.info(TAG,"NowPlaying");}else{playOrPause();}returntrue;}elseif(speechEvent.getActionProperty().equals("Pause")){if(!playerManager.isPlaying()){Log.info(TAG,"已暂停");}else{playOrPause();}返回真;}返回假;};});//下一个注册热词playnextButton.subscribeVoiceEvents(eventnext);//下一首歌曲设置响应事件playnextButton.setSpeechEventListener(newComponent.SpeechEventListener(){@OverridepublicbooleanonSpeechEvent(Componentcomponent,SpeechEventspeechEvent){if(speechEvent.getActionProperty().equals("Next")){nextMusic(component);返回真;}返回假;}});//往期注册热词playpreButton.subscribeVoiceEvents(eventpre);//上一首歌曲设置响应事件playpreButton.setSpeechEventListener(newComponent.SpeechEventListener(){@OverridepublicbooleanonSpeechEvent(Componentcomponent,SpeechEventspeechEvent){if(speechEvent.getActionEquals(("Previoussong")){prevMusic(组件);返回真;}返回假;}});remotePlay.setClickedListener(mShowDeviceListListener);//为转接按钮注册热词remotePlay.subscribeVoiceEvents(eventremote);//设置弹出事件的转移按钮remotePlay.setSpeechEventListener(speech_mShowDeviceListListener);}这里只展示核心部分的代码,具体含义看名字就知道了。具体可以参考分布式传输和转账部分,这里简单回顾一下。在这种情况下,任何动态变化的数据都需要迁移和恢复。6.关于旋转动画创建属性动画/*属性动画*/privateAnimatorPropertyanimatorProperty;初始化一个属性对象//初始化属性动画对象musicPosters是一个Image组件animatorProperty=musicPosters.createAnimatorProperty();animatorProperty.setCurveType(Animator.CurveType.LINEAR);start//让他循环下去animatorProperty.rotate(360+musicPosters.getRotation()).setDuration(100000).setLoopedCount(-1).start();暂停、重置animatorProperty.stop();animatorProperty.reset();各种操作都可以在合适的位置执行。七、结语这次我们主要是在分布式音乐播放器的案例中加入了智慧屏特有的可见可说的功能,以及一些简单的优化和动画。手机、平板也可以进行类似操作。可以参考分布式语音摄像头,但相比之下,我还是觉得看和说的功能更加清晰易用。了解更多开源信息,请访问:51CTO开源基础软件社区https://ost.51cto.com。
