之前大家看過了 Java 版的《HarmonyOS 分布式之仿抖音應用》,現在講講 JS 如何實現分布式仿抖音應用,通過 JS 方式開發視頻播放,分布式設備遷移,評論,通過 Java 和 JS 交互,獲取設備信息,選擇設備信息做分布式遷移。
功能:分布式遷移到不同設備,視頻進行評論,播放視頻,可以像抖音一樣切換視頻,可以點贊,分享等操作。
開發版本:sdk6,DevEco Studio3.0 Beta1。
主要代碼
①視頻播放鴻蒙 js 中有專門【video】的組件,并且非常完善,可以直接使用:
https://developer.harmonyos.com/cn/docs/documentation/doc-references/js-components-media-video-0000000000611764
<videoid='playerId{{$idx}}'src='{{$item.path}}'muted='false'autoplay='true'
controls="false"onprepared='preparedCallback'onstart='startCallback'onpause='pauseCallback'
onfinish='finishCallback'onerror='errorCallback'onseeking='seekingCallback'
onseeked='seekedCallback'
ontimeupdate='timeupdateCallback'style="object-fit:contain;width:100%;"
onlongpress='change_fullscreenchange'onclick="change_start_pause"loop='true'
starttime="0"
>
video>
js 代碼中視頻資源:
list:[{
path:"/common/video/video1.mp4"
},{
path:"/common/video/video2.mp4"
},{
path:"/common/video/video3.mp4"
},{
path:"/common/video/video4.mp4"
},{
path:"/common/video/video5.mp4"
},{
path:"/common/video/video6.mp4"
}]
②仿抖音視頻切換
有關視頻切換的開發 js 中也提供了對應的組件【swiper】,可以直接使用來進行視頻切換:
https://developer.harmonyos.com/cn/docs/documentation/doc-references/js-components-container-swiper-0000000000611533
<swiperclass="swiper-content"id="swiper"index="{{player_index}}"
indicator="false"loop="true"digital="false"vertical="true"onchange="changeVideo">
<stackclass="stack-parent"for="list">
<divclass="videosource">
<videoid='playerId{{$idx}}'src='{{$item.path}}'muted='false'autoplay='true'
controls="false"onprepared='preparedCallback'onstart='startCallback'onpause='pauseCallback'
onfinish='finishCallback'onerror='errorCallback'onseeking='seekingCallback'
onseeked='seekedCallback'
ontimeupdate='timeupdateCallback'style="object-fit:contain;width:100%;"
onlongpress='change_fullscreenchange'onclick="change_start_pause"loop='true'
starttime="0"
>
video>
div>
stack>
swiper>
③評論功能添加
評論功能使用了鴻蒙 js 中了兩個組件【list】(負責列表展示) 和【input】(負責信息發送),可參見有關文檔。
https://developer.harmonyos.com/cn/docs/documentation/doc-references/js-components-container-list-0000000000611496
https://developer.harmonyos.com/cn/docs/documentation/doc-references/js-components-basic-input-0000000000611673
評論功能有兩部分,評論列表和評論發送輸入框。
<divclass="pinglun"style="visibility:{{ifhidden}};">
<divstyle="height:32%;background-color:transparent;"onclick="hideenbg">
<text>text>
div>
<listclass="todo-wrapper"divider="true"style="divider-color:darkgrey;">
<list-itemfor="{{todolist}}"class="todo-item">
<divclass="photo">
<imageclass="image-set"src="/common/images/science6.png">image>
<textclass="todo-title"style="font-size:14fp;margin-left:10px;">{{$item.name}}
text>
div>
<textclass="todo-title"style="font-size:14fp;margin-top:5px;">{{$item.detail}}text>
list-item>
list>
<divclass="butt">
<inputid="input"class="input"type="text"value="{{content}}"maxlength="20"enterkeytype="send"
placeholder="{{placecontent}}"onchange="change"
onenterkeyclick="enterkeyClick">
input>
<buttonclass="last"onclick="sendmessage">發送button>
div>
div>
功能實現邏輯:
change(e){//監聽輸入框信息變化獲取信息
this.message=e.value;
console.log("message==="+this.message)
},
sendmessage(){//提交信息后組織數據刷新界面
this.todolist.push({
name:'王者',
detail:this.message,
})
this.content="";
this.message="";
},
④JS 和 Java 交互獲取設備信息
在實現分布式設備遷移的時候查找 js 沒有找到獲取設備信息的有關接口,所以考慮通過 js 和 Java 相互調用實現。通過 jsFA 調用 Java PA機制,實現數據的獲取和傳遞。
js 端實現如下:重點:
-
Ability 類型,對應 PA 端不同的實現方式:0:Ability,1:Internal Ability。
- syncOption PA 側請求消息處理同步/異步選項:0:同步方式,默認方式,1:異步方式。
initAction(code){
varactionData={};
actionData.firstNum=1024;
actionData.secondNum=2048;
varaction={};
action.bundleName="com.corecode.video.videoplayer";//包名
action.abilityName="com.corecode.video.videoplayer.DeviceInternalAbility";//包名+類名
action.messageCode=code;//消息編碼
action.data=actionData;//傳遞數據
action.abilityType=1;//ability類型
action.syncOption=1;//同步還是異步類型
returnaction;
},
getLevel:asyncfunction(){
try{
varaction=this.initAction(1001);
varresult=awaitFeatureAbility.callAbility(action);
console.info("result="+result);
this.deviceId=JSON.parse(JSON.parse(result).result);
console.log("deviceId=="+this.deviceId)
this.devicelist="visible";
}catch(pluginError){
console.error("getBatteryLevel:PluginError="+pluginError);
}
}
Java 端實現如下:
Java 端需要創建一個 ability 服務繼承 AceInternalAbility 具體是使用哪種類型,看上面的解釋。
創建后需要注冊,比如我創建的是 InternalAbility 這樣注冊:DeviceInternalAbility.register(this);
packagecom.corecode.video.videoplayer;
publicclassDeviceInternalAbilityextendsAceInternalAbility{
privatestaticfinalHiLogLabelTAG=newHiLogLabel(0,0,"DeviceInternalAbility");
privatestaticfinalintCONNECT_ABILITY=2000;
privatestaticfinalintDISCONNECT_ABILITY=2001;
privatestaticfinalintSEND_MSG=1001;
privatestaticfinalintSUCCESS_CODE=0;
privatestaticfinalintFAIL_CODE=-1;
privatestaticDeviceInternalAbilityINSTANCE;
privateStringselectDeviceId;
/**
*defaultconstructor
*
*@paramcontextabilitycontext
*/
publicDeviceInternalAbility(AbilityContextcontext){
super("com.corecode.video.videoplayer","com.corecode.video.videoplayer.DeviceInternalAbility");
}
publicDeviceInternalAbility(StringbundleName,StringabilityName){
super(bundleName,abilityName);
}
publicDeviceInternalAbility(StringabilityName){
super(abilityName);
}
/**
*setInternalAbilityHandlerforDistributeInternalAbilityinstance
*
*@paramcontextabilitycontext
*/
staticvoidregister(AbilityContextcontext){
INSTANCE=newDeviceInternalAbility(context);
INSTANCE.setInternalAbilityHandler((code,data,reply,option)->
INSTANCE.onRemoteRequest(code,data,reply,option));
}
/**
*destroyDistributeInternalAbilityinstance
*/
privatestaticvoidunregister(){
INSTANCE.destroy();
}
/**
*defaultdestructor
*/
privatevoiddestroy(){
}
/**
*handclickrequestfromjavascript
*
*@paramcodeACTION_CODE
*@paramdatadatasentfromjavascript
*@paramreplyreplyforjavascript
*@paramoptioncurrentlyexcessive
*@returnwhetherjavascriptclickeventiscorrectlyresponded
*/
privatebooleanonRemoteRequest(intcode,MessageParceldata,MessageParcelreply,MessageOptionoption){
MapreplyResult=newHashMap<>();
switch(code){
//sendmessagetoremotedevice,messagecontainscontrollercommandfromFA
caseSEND_MSG:{
ZSONObjectdataParsed=ZSONObject.stringToZSON(data.readString());
intmessage=dataParsed.getIntValue("message");
////SYNC
//if(option.getFlags()==MessageOption.TF_SYNC){
//reply.writeString(ZSONObject.toZSONString(result));
//}
//ASYNC
//返回結果當前僅支持String,對于復雜結構可以序列化為ZSON字符串上報
Mapresult=newHashMap();
result.put("result",MainAbility.getList());
MessageParcelresponseData=MessageParcel.obtain();
responseData.writeString(ZSONObject.toZSONString(result));
IRemoteObjectremoteReply=reply.readRemoteObject();
try{
remoteReply.sendRequest(0,responseData,MessageParcel.obtain(),newMessageOption());
}catch(RemoteExceptionexception){
returnfalse;
}finally{
responseData.reclaim();
}
break;
}
//toinvokeremotedevice'snewsShareabilityandsendnewsurlwetransfer
caseCONNECT_ABILITY:{
ZSONObjectdataParsed=ZSONObject.stringToZSON(data.readString());
selectDeviceId=dataParsed.getString("deviceId");
break;
}
//whencontrollerFAwenttodestroylifeCycle,disconnectwithremotenewsShareability
caseDISCONNECT_ABILITY:{
unregister();
break;
}
default:
HiLog.error(TAG,"messageCodenothandleproperlyinphonedistributeInternalAbility");
}
returntrue;
}
privatevoidassembleReplyResult(intcode,MapreplyResult,Objectcontent,MessageParcelreply) {
replyResult.put("code",code);
replyResult.put("content",content);
reply.writeString(ZSONObject.toZSONString(replyResult));
}
}
js 調用后會進入 Java 的 onRemoteRequest 函數進行數據解析和組織,然后通過如下接口將需要的結果回傳給 js 做界面展示和操作。
remoteReply.sendRequest(0,responseData,MessageParcel.obtain(),newMessageOption());
獲取設備信息:
List<DeviceInfo>deviceInfos=DeviceManager.getDeviceList(DeviceInfo.FLAG_GET_ONLINE_DEVICE);
⑤分布式遷移
鴻蒙中分布式遷移真的是做到了強大,在 js 中只需要四個函數就能完成分布式遷移。
onSaveData(saveData){//數據保存到savedData中進行遷移。
vardata={
list:this.list,
player_index:this.player_index,
};
Object.assign(saveData,data)
},
onRestoreData(restoreData){//收到遷移數據,恢復。
console.info('====onRestoreData'+JSON.stringify(restoreData))
this.list=restoreData.list
this.player_index=restoreData.player_index
this.$element('swiper').swipeTo({
index:this.player_index
});
},
onCompleteContinuation(code){//遷移完成
console.log("onCompleteContinuation==="+code)
},
onStartContinuation(){//遷移開始
returntrue;
},
遷移:上面的四個有關函數設置好后執行下面的接口就能實現分布式遷移了。
continueVideoAbility:asyncfunction(){
letconti=awaitFeatureAbility.continueAbility();
}
⑥權限
需要加上需要的權限:
"reqPermissions":[
{
"reason":"",
"usedScene":{
"ability":[
"MainAbility"
],
"when":"inuse"
},
"name":"ohos.permission.DISTRIBUTED_DATASYNC"
},
{
"name":"ohos.permission.DISTRIBUTED_DEVICE_STATE_CHANGE"
},
{
"name":"ohos.permission.GET_DISTRIBUTED_DEVICE_INFO"
},
{
"name":"ohos.permission.GRT_BUNDLE_INFO"
},
{
"name":"ohos.permission.INTERNET"
}
]
源碼地址【 分布式仿抖音視頻】:
https://gitee.com/dot_happydz_admin/video-player
-
應用
+關注
關注
2文章
438瀏覽量
34137 -
鴻蒙系統
+關注
關注
183文章
2634瀏覽量
66218 -
HarmonyOS
+關注
關注
79文章
1967瀏覽量
30017
原文標題:鴻蒙版“抖音”,體驗賊好!
文章出處:【微信號:gh_834c4b3d87fe,微信公眾號:OpenHarmony技術社區】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論