HarmonyOS鸿蒙Next仿抖音短视频应用首发

HarmonyOS鸿蒙Next仿抖音短视频应用首发

本节演示,如何结合HarmonyOS组件和分布式能力等,构建一款仿抖音短视频展示应用。应用需实现滑动切换视频功能、评论功能、分布式流转功能等。

创建应用

创建名为“Douyin”的Java UI应用。这里,我们选用了Video Player Ability(Java)模板(如下图所示),以便快速初始化一个视频播放的应用。

cke_166.png

cke_167.png

预览器里面预览应用,可以看到效果如下图所示。

cke_168.png

从上述预览器中可以看出,整体界面已经是一个视频播放器的雏形了。

视频播放器播放视频

可以直接在模拟器里面运行应用,可以看到视频播放器播放视频的效果。

cke_169.png

探索项目结构

其实这个应用是多个entry模块的应用,从代码结构也可以看出。

cke_170.png

可以这么理解,entry模块是用于Phone设备的,而entrytv是用于TV设备的。commonlib则是所有设备通用的模块。

实现滑动切换视频

禁用VideoPlayerView里面的滑动事件

把initVideoView方面里面的这段代码删除了

// Gesture callback
setDraggedListener(
DRAG_HORIZONTAL_VERTICAL,
new DraggedListener() {
@Override
public void onDragDown(Component component, DragInfo dragInfo) {
HiLog.info(VIDEO_BOX_LABEL, "VideoView onDragDown");
}
@Override
public void onDragStart(Component component, DragInfo dragInfo) {
}
@Override
public void onDragUpdate(Component component, DragInfo dragInfo) {
if (!isDraggingPlayer) {
if (Math.abs(dragInfo.xOffset) >= Math.abs(dragInfo.yOffset)) {
// Adjusting the progress
GESTURE_FLAG = GESTURE_MODIFY_PROGRESS;
// Hold pause while dragging the progress bar
if (isPlaying()) {
videoPlayer.pause();
needResumeStatus = true;
}
// Keep control area displayed
executeAnim(true);
} else {
// Adjusting the volume
HiLog.info(VIDEO_BOX_LABEL, "Adjusting the volume");
GESTURE_FLAG = GESTURE_MODIFY_VOLUME;
}
curDownPlayingTime = getCurrentPosition();
isDraggingPlayer = true;
}
if (GESTURE_FLAG == GESTURE_MODIFY_PROGRESS) {
// The control area does not disappear when the progress bar is being adjusted.
resetFadedOutTime();
if (Math.abs(dragInfo.xOffset) > MIN_OFFSET_FOR_PROGRESS_ADJUSTMENT) {
if (dragInfo.xOffset > 0) {
if (curDownPlayingTime + PROGRESS_STEP < getDuration()) {
curDownPlayingTime += PROGRESS_STEP;
} else {
curDownPlayingTime = getDuration();
}
} else {
if (curDownPlayingTime > PROGRESS_STEP) {
curDownPlayingTime -= PROGRESS_STEP;
} else {
curDownPlayingTime = 0;
}
}
if (curDownPlayingTime < 0) {
curDownPlayingTime = 0;
HiLog.error(VIDEO_BOX_LABEL, "Error curDownPlayingTime");
}
HiLog.debug(VIDEO_BOX_LABEL, "curDownPlayingTime = " + curDownPlayingTime);
seekTo(curDownPlayingTime);
}
} else if (GESTURE_FLAG == GESTURE_MODIFY_VOLUME) {
if (Math.abs(dragInfo.yOffset) > MIN_OFFSET_FOR_VOLUME_ADJUSTMENT) {
setVolume(dragInfo.yOffset > 0 ? -VOLUME_STEP : VOLUME_STEP);
}
} else {
HiLog.error(VIDEO_BOX_LABEL, "Error gesture flag");
}
}
@Override
public void onDragEnd(Component component, DragInfo dragInfo) {
// Resume Dragging flag
isDraggingPlayer = false;
if (GESTURE_FLAG == GESTURE_MODIFY_PROGRESS) {
if (needResumeStatus) {
start();
}
needResumeStatus = false;
}
// Resume gesture flag
GESTURE_FLAG = 0;
}
@Override
public void onDragCancel(Component component, DragInfo dragInfo) {
}
});

上述代码原意是通过拖动,来实现视频进度的快进或者快退。这里将拖动事件先去除,后面用该拖动事件来实现视频的切换。

在VideoPlayAbilitySlice增加对VideoPlayerView的拖动事件处理

在VideoPlayAbilitySlice里面, VideoPlayerView的变量名是player,在onStart方法中,增加对player拖动事件处理:

player.setDraggedListener(
Component.DRAG_HORIZONTAL_VERTICAL,
new Component.DraggedListener() {
@Override
public void onDragDown(Component component, DragInfo dragInfo) {
}
@Override
public void onDragStart(Component component, DragInfo dragInfo) {
}
@Override
public void onDragUpdate(Component component, DragInfo dragInfo) {
int size = videoService.getAllVideoInfo().getDetail().size();
HiLog.info(LABEL, "size:%{public}s, currentPlayingIndex:%{public}s", size, currentPlayingIndex);
currentPlayingIndex = (++currentPlayingIndex) % size;
HiLog.info(LABEL, "size:%{public}s, currentPlayingIndex:%{public}s", size, currentPlayingIndex);
playbackNext(videoService.getVideoInfoByIndex(currentPlayingIndex));
}
@Override
public void onDragEnd(Component component, DragInfo dragInfo) {
}
@Override
public void onDragCancel(Component component, DragInfo dragInfo) {
}
});

上述代码实现了,当滑动视频播放器时,就会播放下个视频。

增加评论功能

视频播放器的布局文件是在hm_sample_ability_video_box.xml。他原来的是使用的StackLayout类型的布局,这里我们需要改为DependentLayout类型的布局。

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:id="$+id:root_layout"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:background_element="#FFFFFFFF"
ohos:orientation="vertical">
<com.waylau.hmos.douyin.player.ui.widget.media.VideoPlayerView
ohos:id="$+id:video_view"
ohos:height="250vp"
ohos:width="match_parent"/>
<DirectionalLayout
ohos:id="$+id:comment_layout"
ohos:align_parent_bottom="true"
ohos:width="match_parent"
ohos:height="50vp"
ohos:orientation="horizontal"
ohos:background_element="#ffffff"
ohos:alignment="vertical_center"
ohos:left_padding="20vp"
ohos:right_padding="20vp">
<TextField
ohos:id="$+id:comment_text_field"
ohos:width="270vp"
ohos:height="30vp"
ohos:left_padding="5vp"
ohos:right_padding="10vp"
ohos:text_alignment="vertical_center"
ohos:text_size="15vp"
ohos:hint="输入评论内容"/>
<Button
ohos:width="50vp"
ohos:height="30vp"
ohos:text_size="20fp"
ohos:text="评论"
ohos:background_element="#007CFD"/>
</DirectionalLayout>
</DirectionalLayout>

评论界面效果如下。

cke_171.png

显示评论内容

增加显示评论内容的布局

修改hm_sample_ability_video_box.xml,增加显示评论内容的布局。

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:id="$+id:root_layout"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:background_element="#FFFFFFFF"
ohos:orientation="vertical">
<com.waylau.hmos.douyin.player.ui.widget.media.VideoPlayerView
ohos:id="$+id:video_view"
ohos:height="250vp"
ohos:width="match_parent"/>
<DirectionalLayout
ohos:id="$+id:comment_show_layout"
ohos:align_parent_bottom="true"
ohos:width="match_parent"
ohos:height="50vp"
ohos:orientation="horizontal"
ohos:background_element="#ffffff"
ohos:alignment="vertical_center"
ohos:left_padding="20vp"
ohos:right_padding="20vp">
<Text
ohos:id="$+id:text_auto_scrolling"
ohos:text="欢迎评论"
ohos:height="match_content"
ohos:width="match_parent"
ohos:text_size="28fp"
ohos:text_color="#0000FF"
ohos:italic="true"
ohos:text_weight="700"
ohos:text_font="serif"/>
</DirectionalLayout>
<DirectionalLayout
ohos:id="$+id:comment_layout"
ohos:align_parent_bottom="true"
ohos:width="match_parent"
ohos:height="50vp"
ohos:orientation="horizontal"
ohos:background_element="#ffffff"
ohos:alignment="vertical_center"
ohos:left_padding="20vp"
ohos:right_padding="20vp">
<TextField
ohos:id="$+id:comment_text_field"
ohos:width="270vp"
ohos:height="30vp"
ohos:left_padding="5vp"
ohos:right_padding="10vp"
ohos:text_alignment="vertical_center"
ohos:text_size="15vp"
ohos:hint="输入评论内容"/>
<Button
ohos:id="$+id:comment_button"
ohos:width="50vp"
ohos:height="30vp"
ohos:text_size="20fp"
ohos:text="评论"
ohos:background_element="#007CFD"/>
</DirectionalLayout>
</DirectionalLayout>

评论区显示效果如下。

cke_172.png

增加对评论内容的效果展示

在VideoPlayAbilitySlice的onStart方法中,增加对评论内容的效果展示:

// 评论的内容,以跑马灯的方式展现
Text textAutoScrolling =
(Text) findComponentById(ResourceTable.Id_text_auto_scrolling);
// 跑马灯效果
textAutoScrolling.setTruncationMode(Text.TruncationMode.AUTO_SCROLLING);
// 始终处于自动滚动状态
textAutoScrolling.setAutoScrollingCount(Text.AUTO_SCROLLING_FOREVER);
// 启动跑马灯效果
textAutoScrolling.startAutoScrolling();

上述代码,将使评论的内容以跑马灯的方式展现。

监听评论按钮事件

在VideoPlayAbilitySlice的onStart方法中,监听评论按钮事件,当发送评论内容时,评论的内容,将会在评论区展示。代码如下:

Button button =
(Button) findComponentById(ResourceTable.Id_comment_button);
TextField commentTextField =
(TextField) findComponentById(ResourceTable.Id_comment_text_field);
// 为评论按钮设置点击事件回调
button.setClickedListener(listener -> {
textAutoScrolling.setText(commentTextField.getText());
commentTextField.setText("");
// 重新启动跑马灯效果
textAutoScrolling.startAutoScrolling();
});

运行运行应用,效果如下:

cke_173.png

实现分布式流转功能

我们期望将手机上的视频,流转到更加大屏的TV上。

通过Super device的方式,来同时启动Phone和TV模拟器。

cke_174.png

分别在Phone和TV模拟器上安装entry和entrytv模块。

cke_175.png

在Phone模拟器上观看视频时,点击右上角的流转按钮。进行流转。此时,会要求选择要流转的设备。

cke_176.png

这里我们选择“华为智慧屏”。此时可以看到,原本在手机上的视频,流转到了智慧屏上继续播放,获得了更好的大屏观影体验。

cke_177.png

总结

以上应用实现了滑动切换视频功能、评论功能、分布式流转功能等功能。特别是借助DevEco Studio的Video Player Ability(Java)模板,可以大大简化视频播放器的开发流程。

完整演示效果可以看我B站视频:

https://www.bilibili.com/video/BV18f4y177QL/

更多HarmonyOS使用案例,可以参见我的开源书《跟老卫学HarmonyOS开发》:

https://github.com/waylau/harmonyos-tutorial


更多关于HarmonyOS鸿蒙Next仿抖音短视频应用首发的实战教程也可以访问 https://www.itying.com/category-93-b0.html

14 回复

我们的应用现在增加了一个短视频信息流模块,相当于多了一个广告变现场景,实测收益上升很明显。百度查一下:短视频api,有很多短视频内容服务商,接入非常简单方便。

更多关于HarmonyOS鸿蒙Next仿抖音短视频应用首发的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


跟着学似乎还好,但是当初也算是很惊艳了

只要动起手来,就不难也~

视频滑动用到list容器,不是修改控制器吧?

上面有讲到如何设置滑动事件~

楼主写得真详细,学到了,点赞支持一下。

多谢支持~~~~~~~~~~~~~~

短视频已经火到会拿来当案例的程度了,时间真快

选择设备那个窗口是怎么调出来的?是系统自带的吗

这个是需要代码实现的,本质上是需要查询周边的设备列表

窗口是自己画的吗?还是有模板

有模板,可以基于模板改~

HarmonyOS鸿蒙Next仿抖音短视频应用首发,展示了鸿蒙系统在多媒体处理和高性能渲染方面的能力。该应用利用鸿蒙的分布式技术,实现跨设备无缝体验,支持多端协同操作。鸿蒙的ArkUI框架和高效的内存管理机制,确保了应用的流畅运行和低延迟。此外,鸿蒙的HMS Core提供了丰富的API,支持视频处理、推荐算法等核心功能。该应用的首发进一步验证了鸿蒙在复杂应用场景下的技术成熟度。

这个仿抖音短视频应用的实现很好地展示了HarmonyOS的核心能力。通过Video Player Ability模板快速搭建视频播放功能,并实现了几个关键特性:

  1. 滑动切换视频功能:
  • 通过重写VideoPlayerView的拖动事件监听器
  • 使用onDragUpdate监听滑动动作
  • 配合currentPlayingIndex实现视频切换逻辑
  1. 评论功能:
  • 采用DirectionalLayout布局构建评论界面
  • 使用TextField和Button组件实现评论输入
  • 通过Text组件的跑马灯效果展示评论内容
  1. 分布式流转:
  • 利用HarmonyOS的分布式能力
  • 通过entry和entrytv模块实现多设备适配
  • 使用Super device功能演示手机到TV的流转

这个案例很好地结合了HarmonyOS的UI组件、手势交互和分布式特性,展示了如何快速开发一个完整的短视频应用。开发者可以基于这个示例进一步扩展功能,如添加点赞、分享等社交功能。

回到顶部