前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >鸿蒙开发实战案例:视频截取gif图

鸿蒙开发实战案例:视频截取gif图

原创
作者头像
小帅聊鸿蒙
发布2025-03-05 20:37:12
发布2025-03-05 20:37:12
230
举报
文章被收录于专栏:鸿蒙开发笔记鸿蒙开发笔记

介绍

本示例介绍了如何截取视频的一段内容制作gif图片。该场景多出现在长视频类应用。使用FFmpeg命令对视频进行截取gif图。

效果图预览

使用说明

  • 点击“本地视频截取gif”或“在线视频截取gif”的视频,进入视频播放页面。
  • 在视频播放页面中点击“gif”按钮,进入视频截取gif图页面。
  • 可以拖动底部时间轴的选中框来选取需要截取的gif的片段,然后点击“下一步”按钮,进入gif图生成页面。
  • 在gif图生成页面稍等片刻会生成gif图片,可以将gif图保存至相册。

实现步骤

  1. 打开视频播放页面,根据视频是本地视频还是线上视频选择设置avPlayer的url。如果是线上视频,使用边缓存边播放的方式,需要记录缓存文件的本地路径。
代码语言:ts
复制
    if (this.url.startsWith(getContext().filesDir)) {
      this.srcFilePath = this.url;
      let file = await fs.open(this.url);
      this.avPlayer.url = `fd://${file.fd}`;
    } else {
      let that = this;
    
      class MyCacheListener implements CacheListener {
        onCacheAvailable(cacheFilePath: string, url: string, percentsAvailable: number): void {
          AppStorage.setOrCreate('currentCachePercent', percentsAvailable);
          if (!that.srcFilePath) {
            // 记录缓存文件的本地路径
            that.srcFilePath = cacheFilePath;
          }
        }
      }
    
      GlobalProxyServer?.getInstance()?.getServer()?.registerCacheListener(new MyCacheListener(), this.url);
    
      let proxyUrl: string | undefined =
        await GlobalProxyServer?.getInstance()?.getServer()?.getProxyUrl(this.url);
      if (proxyUrl.startsWith(getContext().cacheDir)) {
        this.srcFilePath = proxyUrl;
        const file = fs.openSync(this.srcFilePath, fs.OpenMode.READ_ONLY);
        proxyUrl = `fd://${file.fd}`;
      }
      this.avPlayer.url = proxyUrl;
   }
  1. 根据视频播放页面上"gif"按钮的时间点,按一定规则确定截取的时间范围,进入选取生成gif时间片段页面,通过MP4Parser获取每秒的视频帧图片,展示在时间轴上。
代码语言:ts
复制
    MP4Parser.getFrameAtTimeRang(startTimeUs, endTimeUs, MP4Parser.OPTION_CLOSEST, frameCallBack);
  1. 时间轴选择框框取范围处理,具体处理可以查看RangeSeekBarView.ets文件,
代码语言:ts
复制
    let touchXNew:number = this.clearUndefined(event?.offsetX);
    let deltaX:number = touchXNew - this.touchXOld;
    if (this.touchType == TouchType.TouchLeftThumb) {
      this.leftThumbUpdate(deltaX);
      this.onRangeValueChanged();
    } else if (this.touchType == TouchType.TouchRightThumb) {
      this.rightThumbUpdate(deltaX);
      this.onRangeValueChanged();
    } else if (this.touchType == TouchType.TouchMiddleThumb) {
      if ((deltaX < 0 && this.leftThumbRect[0] > 0)
            || (deltaX > 0 && this.rightThumbRect[2] < this.componentMaxWidth)) {
        this.leftThumbUpdate(deltaX);
        this.rightThumbUpdate(deltaX);
        this.onRangeValueChanged();
      }
    }

    this.touchXOld = this.clearUndefined(event?.offsetX);  
DD一下:欢迎大家关注公众号<程序猿百晓生>,可以了解到一下知识点。
代码语言:erlang
复制
1.OpenHarmony开发基础
2.OpenHarmony北向开发环境搭建
3.鸿蒙南向开发环境的搭建
4.鸿蒙生态应用开发白皮书V2.0 & V3.0
5.鸿蒙开发面试真题(含参考答案) 
6.TypeScript入门学习手册
7.OpenHarmony 经典面试题(含参考答案)
8.OpenHarmony设备开发入门【最新版】
9.沉浸式剖析OpenHarmony源代码
10.系统定制指南
11.【OpenHarmony】Uboot 驱动加载流程
12.OpenHarmony构建系统--GN与子系统、部件、模块详解
13.ohos开机init启动流程
14.鸿蒙版性能优化指南
.......
  1. 点击"下一步"按钮,会出现gif生成页面,根据起始时间和截取长度通过MP4Parser的ffmpegCmd方法生成gif图片。
代码语言:ts
复制
    MP4Parser.ffmpegCmd("ffmpeg -i " + srcFilePath + " -ss " + startTime + " -t " + duration + " " + dst, callBack);

高性能知识点

不涉及

工程结构&模块类型

代码语言:shell
复制
   videocreategif                                     // har
   |---components
   |   |---CustomLoadingDialog.ets                    // 自定义等待弹窗
   |   |---GifCreateView.ets                          // gif生成页面
   |   |---RangeSeekBarView.ets                       // 时间轴选中框
   |   |---SelectGifTimeFrameView.ets                 // 选取生成gif时间片段页面
   |   |---VideoThumbListView.ets                     // 时间轴小图展示
   |---model                                         
   |   |---BannerInfo.ets                             // banner信息
   |   |---GlobalProxyServer.ets                      // 边缓存边播放服务器管理
   |   |---VideoInfo.ets                              // 视频信息
   |---util
   |   |---Logger.ets                                 // 日志打印工具  
   |   |---TimeTools.ets                              // 时长数据转换工具
   |---view
   |   |---VideoCreateGif.ets                         // 视频项展示页面
   |   |---VideoPlayPage.ets                          // 视频播放页面

写在最后

如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:

  • 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力;
  • 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识;
  • 想要获取更多完整鸿蒙最新学习知识点,可关注B站:码牛课堂;

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 介绍
  • 效果图预览
  • 实现步骤
    • DD一下:欢迎大家关注公众号<程序猿百晓生>,可以了解到一下知识点。
  • 高性能知识点
  • 工程结构&模块类型
  • 写在最后
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档