前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >从零开始仿写一个抖音App——视频编辑SDK开发(一)

从零开始仿写一个抖音App——视频编辑SDK开发(一)

作者头像
何时夕
发布于 2019-11-21 06:58:44
发布于 2019-11-21 06:58:44
2K00
代码可运行
举报
文章被收录于专栏:求索之路求索之路
运行总次数:0
代码可运行

本文首发于微信公众号——世界上有意思的事,搬运转载请注明出处,否则将追究版权责任。交流qq群:859640274

大家好久不见,又有一个多月没有发文章了。不知道还有哪些读者记得我的 从零开始仿写抖音App 的系列文章,这个系列的文章已经很久没有更新了,最后一篇文章是我开始开发 视频编辑SDK 时写的。当时踏入到了一个新的领域里,未知的东西太多了,导致接下来的大半年都没有更新相关的文章。 但是别以为我已经放弃了,今天对于我来说是一个值得纪念的日子,2019年10月28日 我终于将 视频编辑SDK 的最简版本给完成了,我将这个 视频编辑SDK 命名为 WSVideoEditor,接下来的一段时间里我计划更新 4 篇解析该 SDK 的相关文章,WsVideoEditor 中的代码我也会随着文章同步更新。当 SDK 解析完毕之后 从零开始仿写一个抖音App 系列文章将会踏出最关键的一步。

阅读须知:

本文分为以下章节,读者可按需阅读:

  • 1.项目介绍
  • 2.SDK功能介绍
  • 3.SDK架构以及运行机制介绍
  • 4.VideoDecodeService解析

一、项目介绍

本章我将介绍 WsVideoEditor 项目的基本结构、组织方式以及运行方式。需要大家把项目 clone 下来跟着我一步步来做。

1.基本结构

图1:总结构

我们看着图1,一个个来讲:

  • 1.android:顾名思义,这个目录下是一个 Android 项目,去掉 .gradle、build、.idea 等等 ignore 的文件,我们主要关注下面这几个文件夹。

图2:ffmpeg-cpp.png

  • 1.ffmpeg-cpp:如图2,这个文件夹中有 FFMPEG 的头文件与 .so 文件,我们需要将这个库集成到我们的 SDK 中,我们的 编辑SDK 需要有解码视频的能力,解码分为硬解和软解,ffmpeg 就是用于软解的最强开源库。至于如何得到这些东西,我之前写过一篇 FFMPE食用指南 有兴趣的读者可以看看。
  • 2.protobuf-cpp:这个文件夹与 ffmpeg-cpp 类似,里面有 Protobuf For Cpp 的头文件与 .a 文件,因为我们 Native 与 Android/iOS/Linux 的通信方式使用的是 Protobuf,所以我们也需要将 Cpp 层的 Protobuf 集成到我们的 SDK 中。

图3:wsvideoeditor-sdk.png

  • 3.wsvideoeditor-sdk:如图3,这个文件夹是一个 Android Library 项目,我们的 编辑SDK 在 Android 端会以一个独立的 jar 包形式存在。这个目录下的东西比较多,例如 src 目录下是 Java 层的一些封装代码。jni 目录下是一些使用了 Android Native Api 的 Cpp 代码。更详细的解析,会在后面几章。
  • 4.wsvideoeditor-test:这个文件夹则是一个 Android Application 项目,主要是用于编写一些测试 编辑 SDK 的代码。

图4:buildtools.png

  • 2.buildtools:如图4,这个目录下主要存放一些工具脚本,例如目前 build_proto.sh 用于生成 Java 与 Cpp 层的 Protobuf 代码。
  • 3.ios、linux:因为我给 编辑SDK 的定义是一个跨平台的视频编辑SDK,所以未来的想法是 iOS 和 Linux 端也能接入我们的 编辑SDK,目前这两个目录里还啥也没有:-D。

图5:sharedcpp.png

  • 4.sharedcpp:如图5,这个目录里面主要存放与平台无关的 Cpp 代码,因为我们要做的是一个跨平台的视频编辑 SDK,所以尽量多的将与平台无关的代码进行共用,是一个明智的选择。可以看见里面的 prebuilt_protobuf 目录下就有我们使用 build_proto.sh 生成的 Cpp 文件,这些文件就是可以共用的。
  • 5.sharedproto:这里存放着我们定义的 Protobuf 文件。
  • 6.thirdparty:这里存放着一些包含源码的与平台无关的三方库,例如 libyuv。
  • 7.CMakeLists.txt:这个文件主要是为了让 Clion 能够识别我们这个整个项目。

2.如何运行项目

二、SDK功能介绍

这一章我们来介绍一下 编辑SDK 目前有的以及未来会有的功能。编辑SDK 的最终形态会和抖音的视频编辑功能接近,有其他想法的读者也可以在评论区留言或者提 issue。

1.目前有的功能

  • 1.开始播放
  • 2.暂停播放
  • 3.视频音量调整
  • 4.单段视频播放
  • 5.多段视频播放
  • 6.视频 Seek
  • 7.视频边缘模糊填充

2.规划中的功能

  • 1.视频类:
    • 1.按时间轴添加额外的声音
    • 2.按时间轴添加滤镜
    • 3.按时间轴添加静态贴纸、动态贴纸
    • 4.多段视频间转场
  • 2.图片类:
    • 1.添加声音
    • 2.多张图片间的转场
    • 3.照片电影
  • 3.工具类:
    • 1.视频缩略图截取
    • 2.视频元数据读取
  • 4.编码类:
    • 1.导出不同格式的视频
    • 2.更改视频的分辨率、帧率
    • 3.视频转 gif
  • 5.技术类:
    • 1.多进程编解码视频
    • 2.多进程播放视频
    • 3.多进程视频缩略图截取

三、SDK架构以及运行机制介绍

这一章我来介绍一下目前 编辑SDK 的整体架构以及运行机制。

1.编辑SDK架构

图6:编辑SDK架构.png

图6是 编辑SDK 的架构图,这一节我会照着这张图来介绍。

(1).基础API

先从底部看起,底部是整个 SDK 依赖的底层 API 库。

  • 1.FFMPEG:前面简单介绍过,是一个开源的视频库,在我们的项目中主要用于软编解码
  • 2.MediaCodec:是 Android 中的硬编解码 API,相应的 iOS 也有自己的硬编解码方式。
  • 3.OpenGL:是一个开源的图形库,Android 和 iOS 中都有内置 OpenGL ES 作为默认图形库。在我们的项目中主要用于将视频解码后的视频帧绘制到屏幕上去。当然也可以对这些图像做一些效果的变化,例如滤镜、视频/图片转场等等。
  • 4.Libyuv:是 Google 开源的实现各种 YUV 与 RGB 之间相互转换、旋转、缩放的库。
  • 5.Protobuf:是 Google 开源的一种平台无关、语言无关、可扩展且轻便高效的序列化数据结构的协议。在我们的项目中主要用于 Cpp 与 Java、OC、Dart 之间的数据通信。
(2).SDK主体

接着我们再看图片中的主体部分,因为目前只有 Android 端的实现,所以主体部分的上层实现我使用 Android 来代替。

  • 1.Android层架构
    • 1.WSMediaPlayerView:继承于 TextureView,所以其可以提供一个具有 Open GL 环境的线程。对 Surface 家族不了解的同学可以看看这两篇文章:Android绘制机制以及Surface家族源码全解析相机/OpenGL/视频/Flutter和SurfaceView
    • 2.WSMediaPlayer:这个是一个代理了 Native 的 NativeWSMediaPlayer 的 Java 类。该类具有一个播放器应该有的各种 API,例如 play、pause、seek 等等。其实很多 Android 中的系统类都是以这种形式存在的,例如 Bitmap、Surface、Canvas 等等。说到底 Java 只是 Android 系统方便开发者开发 App 的上层语言,系统中大部分的功能最终都会走到 Native 中去,所以读者需要习惯这种代码逻辑
    • 3.AudioPlayer:这个类是基于 Android 中的 AudioTrack 封装的能够播放音频帧的 Java 类。我们在 Native 层也有一个 AudioPlayer。这里与 WSMediaPlayer 相反 Native 层的 AudioPlayer 是一个空壳,Java 层的 AudioPlayer 反向代理了 Native 层的 AudioPlayer,因为在这里 Java 层的 AudioPlayer 才是真正播放音频的东西。
  • 2.Native层架构:这里我们自底向上来剖析,Native 层的架构
    • 1.AudioDecodeService:它负责使用 FFMPEG/MediaCodec,来从视频/音频中解码出某个时间点的音频帧,并且存储在一个音频帧队列中。最终被外部取出音频帧交给音频播放器播放。
    • 2.VideoDecodeService:它和 AudioDecodeService 类似,是使用 FFMPEG/MediaCodec 来从视频中解码出某个时间点的视频帧并且存储在一个视频帧队列中。最终被外部取出视频帧交给 OpenGL 绘制到屏幕上。
    • 3.VideoFramePool:它负责响应外部的 seek 事件,然后使用 FFMPEG/MediaCodec 来从视频中解码出当前时间点的视频帧,然后存储到一个 LruCache 中同时返回 seek 时间点的视频帧。
    • 4.AudioPlayer:前面说过,这个是 Java 层的 AudioPlayer 代理类,主要用于播放 AudioDecodeService 解码出来音频帧。
    • 5.FrameRenderer:这个东西是一个渲染器,在视频播放时用于渲染 VideoDecodeService 不断解码出的视频帧,在视频 seek 的时用于向 VideoDecoderPool 发送 seek 请求,然后渲染返回的视频帧。
    • 6.NativeWSMediaPlayer:用于同步 AudioPlayer 和 FrameRenderer 的音视频播放。即我们一般认为的视频播放器实体,被 Java 层的 WSMediaPlayer 代理着。

2.编辑SDK运行机制

图7:编辑SDK运行机制.png

上一节讲解了 编辑SDK 的架构,这一节在来基于图7讲讲 编辑SDK 的运行机制。

  • 1.经过上一节的介绍,我们都知道了 WSMediaPlayerView 是整个 编辑SDK 的顶级类。所以我们由 WSMediaPlayerView 入手,先看图片最上面。
    • 1.可以看见 WSMediaPlayerView 中会维护一个 30ms的定时循环,这个循环中会不断的调用 draw frame 来驱动 WSMediaPlayer/NativeWSMediaPlayer 进行视频/音频的播放。
    • 2.与此同时,最左边的用户会通过 play、pause、seek 等 API 来更新 NativeWSMediaPlayer 的状态。
    • 3.需要注意的是,WSMediaPlayerView 的定时循环不会被用户的 play、pause、seek 等操作所中断的。
  • 2.再来看看图片左边,这是 WSMediaPlayer 的内部播放机制。要点为 三个循环,两个播放,我们还是自底向上解析。
    • 1.VideoDecodeService:它内部维护了一个可阻塞循环与一个先进先出队列——BlockingQueue,当我们开始播放视频或者 seek 视频到某个时间点的时候,VideoDecodeService 会记录这个开始的时间点,然后不断的解码当前时间点之后的每一帧,每解码出一帧便把这一帧放入 BlockingQueue 中。当队列中的元素达到最大值时,当前的循环就会被阻塞,直到外部将 BlockingQueue 中的 Top 帧消费了,那么循环又会被启动继续解码。需要注意的是:VideoDecodeService 只在视频播放的时候提供视频帧,因为在这个情况下 BlockingQueue 中的视频帧的顺序就是视频真正播放的顺序。
    • 2.VideoFramePool:它内部维护了一个可阻塞请求循环与一个LruCachePool。一般情况下 VideoFramePool 的循环是处于阻塞状态的。当外部 seek 视频的时候,循环会接收到一个请求并开始处理这个请求,如果 LruCachePool 中有 Cache 被命中了,那么就直接返回 Cache,否则将会立即从视频中解码出这个请求中时间点的视频帧存到 LruCachePool 中然后再返回。需要注意的是:VideoFramePool 只在视频 seek 的时候提供视频帧,因为我们的 seek 操作是随机的,所以在这个情况下 VideoDecodeService 无法使用。
    • 3.AudioDecodeService:它与 VideoDecodeService 类似,也维护了一个可阻塞循环先进先出队列,内部的其他行为也类似,只是将视频帧换成了音频帧。
    • 4.FrameRenderer
      • 1.当视频 seek 的时候,其会从 VideoFramePool 中取出 seek 时刻的视频帧绘制它。
      • 2.当视频处于 playing 状态时,它的 drawFrame 方法就会不断被 WSMediaPlayerView 通过定时循环调用并从 VideoDecodeService 中取出当前帧通过 Open GL 绘制它。
    • 5.AudioPlayer:当视频处于 playing 状态时,它也会不断被 WSMediaPlayerView 通过定时循环驱动着从 AudioDecodeService 中取出当前的音频帧,然后通过反向代理将音频帧交给 Java 层的 AudioPlayer 进行播放。

四、VideoDecodeService解析

上一章大概的讲了讲整个 编辑SDK 的整体架构和运行机制,但其实整个 编辑SDK 内部的每一个部分的细节都非常多,所以这一章我会先讲解 VideoDecodeService 的内部细节。其他各个部分则放在后面几篇文章中讲解。与此同时,WsVideoEditor 中的代码也会随着讲解的进行而不断更新。最终形成一个可用的 编辑SDK

1.API讲解

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
-----代码块1----- VideoDecodeService.java
  private native long newNative(int bufferCapacity);
  
  private native void releaseNative(long nativeAddress);
  
  private native void setProjectNative(long nativeAddress, double startTime, byte[] projectData);
  
  private native void startNative(long nativeAddress);
  
  private native String getRenderFrameNative(long nativeAddress, double renderTime);
  
  private native void updateProjectNative(long nativeAddress, byte[] projectData);
  
  private native void seekNative(long nativeAddress, double seekTime);
  
  private native void stopNative(long nativeAddress);
  
  private native boolean endedNative(long nativeAddress);
  
  private native boolean stoppedNative(long nativeAddress);
  
  private native int getBufferedFrameCountNative(long nativeAddress);

如代码块1所示,我们先来讲讲 VideoDecodeService 的 API

  • 1.newNative:由前面几章的讲解我们知道,VideoDecoderService 内部有一个先进先出的阻塞队列,这个方法的入参 bufferCapacity 就是用于设置这个阻塞队列的长度。这个方法调用之后 Native 层会创建一个与 Java 层同名的 VideoDecodeService.cpp 对象。然后返回一个 long 表示这个 Cpp 对象的地址。我们会将其记录在 Java 层,后续要调用其他方法时需要通过这个地址找到相应的对象。
  • 2.releaseNative:因为 Cpp 没有垃圾回收机制,所以 Cpp 对象都是需要手动释放的,所以这个方法就是用于释放 VideoDecodeService.cpp 对象。
  • 3.setProjectNative:因为 Protobuf 是高效的跨平台通信协议,所以 Java 与 Cpp 层的通信方式使用的就是 Protobuf,我们可以看 ws_video_editor_sdk.proto 这个文件,里面定义的 EditorProject 就是两端一起使用的数据结构。这个方法的入参 nativeAddress 就是我们在 1 中获取到的对象地址。入参 startTime 表示起始的解码点,单位是秒。入参 projectData 就是 EditorProject 序列化之后的字节流。
  • 4.startNative:这个方法表示开始解码。
  • 5.getRenderFrameNative:这个方法表示获取 renderTime 这一时刻的帧数据,目前返回到 Java 层的是一个 String,在 Cpp 层后续我们主要就是使用这个方法获取到的帧数据使用 OpenGL 绘制到屏幕上。
  • 6.updateProjectNative:这个方法和 setProjectNative 类似,用于更新 EditorProject。
  • 7.seekNative:我们在看视频的时候,将进度条拖动到某一时刻的操作被称为 seek,在 VideoDecodeService 中的体现就是这个方法,这个方法会将当前的解码时间点设置为 seekTime
  • 8.stopNative:这个方法表示暂停解码。
  • 9.endedNative:返回一个 boolean 表示视频的解码点是否到达了视频的结尾。
  • 10.stoppedNative:返回了一个 boolean 表示当前是否暂停了解码。
  • 11.getBufferedFrameCountNative:返回一个 int,表示当前阻塞队列中有多少个帧,最大不会超过我们在 1 中设置的 bufferCapacity

2.代码分析

这一小节中,我使用一个完整的例子来分析 VideoDecodeService 的源码

  • 1.例子在 TestActivity 中,我们运行项目会看见界面上有三个 Button 和两个 TextView。
  • 2.我们在 initButton 中进行了下面这些操作
    • 1.初始化了 ui。
    • 2.创建了一个 VideoDecodeService.java 类,内部就是调用我们上一节说的 newNative 方法。这个方法最终会进入到 video_decode_service.h 中调用 VideoDecodeService.cpp 的构造方法,构造方法则会创建一个 BlockingQueue.cpp 对象 decoded_unit_queue_,这就是我们一直说的 先进先出阻塞队列
    • 3.构建了一个 EditorProject.java,里面传了一个需要解码的视频路径 /sdcard/test.mp4
  • 3.我们点击 START 按钮
    • 1.stringBuildertimes 是用来记录测试数据的就不说了
    • 2.这里然后调用了 setProject 方法,进过一系列调用链后会通过 jni 进入到代码块3
      • 1.将 buffer 反序列化成 EditorProject.cpp 对象。
      • 2.address 强转 VideoDecodeService.cpp 对象。
      • 3.使用 LoadProject 方法解析出一些数据,例如视频的帧率、宽高等等。有兴趣的读者可以跟进入看看。
      • 4.调用 SetProject 给 VideoDecodeService.cpp 设置 EditorProject.cpp。
    • 3.调用 start 最终也是到代码块3中,调用 Start 方法。我们继续进入 Start 方法中,发现其中是启动了一个线程然后调用 VideoDecodeService::DecodeThreadMain,这个方法内部则是一个 while 循环,每当使用 FFMPEG 解码出一个视频帧的时候就会将这一帧放到 decoded_unit_queue_ 中。当外部没有消费者时,decoded_unit_queue_ 的帧数量将会很快达到阈值(我们设置的是10),此时这个线程就会被阻塞。直到外部消费后,帧数量减少了,本线程将会继续开始解码视频帧,如此往复。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
-----代码块3----- com_whensunset_wsvideoeditorsdk_inner_VideoDecoderService.cc
JNIEXPORT void JNICALL
Java_com_whensunset_wsvideoeditorsdk_inner_VideoDecodeService_setProjectNative
        (JNIEnv *env, jobject, jlong address, jdouble render_pos, jbyteArray buffer) {
    VideoDecodeService *native_decode_service = reinterpret_cast<VideoDecodeService *>(address);
    model::EditorProject project;
    jbyte *buffer_elements = env->GetByteArrayElements(buffer, 0);
    project.ParseFromArray(buffer_elements, env->GetArrayLength(buffer));
    env->ReleaseByteArrayElements(buffer, buffer_elements, 0);
    LoadProject(&project);
    native_decode_service->SetProject(project, render_pos);
}

JNIEXPORT void JNICALL Java_com_whensunset_wsvideoeditorsdk_inner_VideoDecodeService_startNative
        (JNIEnv *, jobject, jlong address) {
    VideoDecodeService *native_decode_service = reinterpret_cast<VideoDecodeService *>(address);
    native_decode_service->Start();
}
  • 4.继续看代码块2,可以看见我启动了一个 Java 层的无限循环线程,每隔 30ms 会 sleep 一下。每次循环我则会调用 getRenderFrame 方法来从 VideoDecodeService 中消费一个视频帧。然后把帧的信息打印到 TextView 上面。其实这里的代码可以类比为视频的播放,VideoDecodeService 不断地在后台线程进行解码按顺序将视频帧放入到队列中,本线程则不断的从队列中取出一帧进行消费,就像视频帧被渲染到屏幕上一样。
  • 5.最下面还有一个 Java 层的无限循环线程,会不断的读取 VideoDecodeService 的其他信息打印到 TextView 上。
  • 6.这一节只是简单的介绍 VideoDecodeService 的运行思路,其实代码里还有很多实现细节,这些细节解析就只能交给读者了,毕竟我比较懒:-D

五、尾巴

终于从零开发仿写一个抖音APP这一系列文章又重新开始更新了,今年以来文章的发表间隔长了很多,写文章的时间也少了很多。但是为了那么多支持、关注我的读者我也不能就这样放弃更新。立一个 flag,今后每个月都要更新一篇文章,希望大家能够多多支持,感谢!!

连载文章

  • 1.从零开始仿写一个抖音app——开始
  • 4.从零开始仿写一个抖音App——日志和埋点以及后端初步架构
  • 5.从零开始仿写一个抖音App——app架构更新与网络层定制
  • 6.从零开始仿写一个抖音App——音视频开篇
  • 7.从零开始仿写一个抖音App——基于FFmpeg的极简视频播放器
  • 8.从零开始仿写一个抖音App——跨平台视频编辑SDK项目搭建
  • 9.从零开始仿写一个抖音App——Android绘制机制以及Surface家族源码全解析
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【Android 音视频开发打怪升级:FFmpeg音视频编解码篇】六、FFmpeg简单合成MP4:视屏解封与重新封装
前面的文章中,对 FFmpg 视频的解码,以及如何利用 OpenGL 对视频进行编辑和渲染,做了详细的讲解,接来非常重要的,就是对编辑好的视频进行编码和保存。
开发的猫
2020/08/11
9490
【Android 音视频开发打怪升级:FFmpeg音视频编解码篇】六、FFmpeg简单合成MP4:视屏解封与重新封装
你的APP与“抖音”,只差一个SDK
短视频因为其自身文化局限性低、时效性高、社交属性强等特点,实力碾压图文信息,具备了与生俱来的国际化传播特性。海外市场作为短视频领域急待挖掘的一片净土,各大平台也已经纷纷意识到了出海的必要性和严峻性。
BestSDK
2018/07/30
9570
你的APP与“抖音”,只差一个SDK
【Android FFMPEG 开发】音视频基础 和 FFMPEG 编译 ( 音视频基础 | MPEG-4 标准 | Android 开发环境 | FFMPEG 交叉编译 | 安卓项目导入配置 )
本篇博客代码及资源下载 : https://download.csdn.net/download/han1202012/10382762
韩曙亮
2023/03/27
3.9K0
【Android FFMPEG 开发】音视频基础 和 FFMPEG 编译 ( 音视频基础 | MPEG-4 标准 |  Android 开发环境 | FFMPEG 交叉编译 | 安卓项目导入配置 )
从零开始仿写一个抖音App——视频编辑SDK开发(二)
如图1,我们知道 OpenGL/OpenGL ES 是一个图形图像渲染框架,它的规范由Khronos组织制定,各个显卡厂商在驱动中实现规范,再由各个系统厂商集成到系统中,最终提供各种语言的 API 给开发者使用。
何时夕
2020/02/24
1.6K0
从零开始仿写一个抖音App——跨平台视频编辑SDK项目搭建
我想看本文的人有很大一部分都是 android 工程师,所以在讲干货之前,我需要讲一讲方法论
何时夕
2019/02/15
1.7K0
得物视频编辑工具优化全指南
随着4G网络的推广和网络带宽的提升,视频成为互联网用户主要的消费载体,用户通过短视频来分享和浏览信息。由此视频的编辑功能越来越重要、越来越普遍。视频编辑的App也如雨后春笋般涌现。
得物技术
2022/11/29
7800
得物视频编辑工具优化全指南
视频编辑SDK测试
短视频编辑SDK支持gif,不同格式的图片,视频文件的拼接导入,编辑,添加特效,合成导出等功能。更具体的介绍可以参照官网的SDK开发文档。https://live.360.cn/developer/doc?page_id=67&item_id=5
CeshirenTester
2022/06/15
4.1K0
从零开始仿写一个抖音App——基于FFmpeg的极简视频播放器GitHub地址
本文首发于简书——何时夕,搬运转载请注明出处,否则将追究版权责任。交流qq群:859640274
何时夕
2018/12/25
2.8K0
从零开始仿写一个抖音App——音视频开篇GitHub地址
我因为主力机是 Mac,所以使用的 IDE 是 CLion,CLion 也是 JetBrain 全家桶的成员之一。使用了 Android Studio 或者 IDEA 的同学可以很方便的切换到这个 IDE 上。此外 CLion 还是一个跨平台的 IDE,也就是说在 Windows Linux 上面也可以使用它。当然 Visual Studio 永远是最强的 IDE(手动狗头)。需要注意的是 CLion 是需要花钱买激活码的,似乎没有免费版开始能免费试用一个月左右的时间,所以激活码的获取途径大家就各显神通吧。
何时夕
2018/12/12
2.3K0
IjkPlayer初始化过程
最近调研做视频秒开,使用B站开源的ijkplayer作为播放器。ijkplayer基于ffmpeg的播放器。
None_Ling
2018/10/24
2K0
我的非线性视频编辑器MiaoVideoCut(1) --- 视频基础知识及环境搭建
所谓视频编码方式就是指通过特定的压缩技术,将某个视频格式的文件转换成另一种视频格式文件的方式。视频流传输中最为重要的编解码标准有国际电联的H.261、H.263、H.264,运动静止图像专家组的M-JPEG和国际标准化组织运动图像专家组的MPEG系列标准,此外在互联网上被广泛应用的还有Real-Networks的RealVideo、微软公司的WMV以及Apple公司的QuickTime等。
瑶瑶
2020/06/03
1.2K0
​FFmpeg 开发(15):学习如何使用 FFmpeg 打造一个自己的通用播放器?
前面 FFmpeg 系列的文章中,已经实现了 FFmpeg 的编译和集成,基于 FFmpeg 实现音视频的播放、录制,并结合 OpenGL 添加丰富的滤镜等功能,这些 demo 基本上将 FFmpeg 使用涉及到的知识点基本上覆盖了。
字节流动
2022/01/21
1.2K0
​FFmpeg 开发(15):学习如何使用 FFmpeg 打造一个自己的通用播放器?
刷抖音上瘾后,决定探究如果做一款类似抖音短视频app
优质短视频内容的产生依赖于短视频的采集和特效编辑,这就要求在进行抖音APP开发时,用到基础的美颜、混音、滤镜、变速、图片视频混剪、字幕等功能,在这些功能基础上,进行预处理,结合OpenGL、AI、AR技术,产生很多有趣的动态贴纸玩法,使得短视频内容更具创意。
Android技术干货分享
2019/06/17
2.5K2
从零开始仿写一个抖音App——app架构更新与网络层定制
讨论1:zsh 对 bash 的支持并不是完全的,如果运行纯 bash 有时候会出问题建议不要在服务器上用。
何时夕
2018/10/11
1.5K0
从零开始仿写一个抖音App——app架构更新与网络层定制
鸿蒙NEXT版仿抖音快手App的视频播放组件
“仿抖音快手”的App项目在Android系统中有成熟的实战案例,具体参见《Android Studio开发实战:从零基础到App上线(第3版)》第14章的“14.4 实战项目:仿抖音的短视频分享”,该项目的前后端通讯方式采用HTTP接口实现,既支持向服务端上传短视频,也支持从服务端拉取短视频观看,并且在多部Android真机上测试通过,具备很高的学习研究价值。
aqi00
2024/11/25
2190
鸿蒙NEXT版仿抖音快手App的视频播放组件
短视频 SDK 开发 (一) 开发一款短视频 SDK 需要具备哪些知识?
前言 2020 年要属什么最火,肯定是短视频和直播带货了。我自己基本上每天晚上睡觉之前都会刷一会儿 douyin 短视频,不得不承认 douyin 的推荐算法是真 nb ,推荐的都是我的最爱 ? 。那
音视频开发进阶
2020/09/24
1.9K0
短视频 SDK 开发 (一) 开发一款短视频 SDK 需要具备哪些知识?
从零开始写一个抖音App——开始一、写在前面二、项目概述三、尾巴
一、写在前面 这个坑可能会持续很久,之前开过好几个坑,但是都不长久。原因是计划赶不上变化。每过一段时间我都会感觉有更重要的事情要去做,所以之前开的坑就被我抛弃了。但是这一次不同,具体的不同点我会在下面一一列举出来。 1.关于目的:作者目前在抖音的竞品里面做android端的视频拍摄和编辑这块。大公司大家也知道,各个业务都是分层的,所以我们平时的业务都是在音视频架构组封装的sdk之上进行的。所以一旦时间长久了自身的竞争力就会减弱,毕竟没有掌握“核心科技”。好在sdk的源码是内部开放的,所以我可以读读源码
何时夕
2018/08/03
1.2K0
【Android 音视频开发:FFmpeg音视频编解码篇】三、Android FFmpeg视频解码播放
本文很长,因为可能有比较多的小伙伴对 JNI C/C++ 不是很熟悉,所以本文比较详细的对 FFmpeg 用到的代码进行讲解,完整的演示了一遍 FFmpeg 的解码和渲染过程,并且对解码过程进行了封装。
开发的猫
2020/04/01
3.2K0
音视频面试题集锦第 15 期 | 编辑 SDK 架构 | 直播回声 | 播放器架构
从业务角度来看,视频编辑 SDK 上层的功能模块通常包括:抽帧模块、预览播放器模块、转码模块。
关键帧
2024/01/29
3960
音视频面试题集锦第 15 期 | 编辑 SDK 架构 | 直播回声 | 播放器架构
美摄iOS端短视频SDK视频编辑的流程及方法
美摄短视频SDK提供视频编辑功能,支持视频图片素材混合导入、滤镜、配音、时间特效、画中画等丰富的编辑效果。本文介绍iOS端短视频SDK视频编辑的流程及方法。
用户10201420
2022/12/01
2.1K0
美摄iOS端短视频SDK视频编辑的流程及方法
推荐阅读
【Android 音视频开发打怪升级:FFmpeg音视频编解码篇】六、FFmpeg简单合成MP4:视屏解封与重新封装
9490
你的APP与“抖音”,只差一个SDK
9570
【Android FFMPEG 开发】音视频基础 和 FFMPEG 编译 ( 音视频基础 | MPEG-4 标准 | Android 开发环境 | FFMPEG 交叉编译 | 安卓项目导入配置 )
3.9K0
从零开始仿写一个抖音App——视频编辑SDK开发(二)
1.6K0
从零开始仿写一个抖音App——跨平台视频编辑SDK项目搭建
1.7K0
得物视频编辑工具优化全指南
7800
视频编辑SDK测试
4.1K0
从零开始仿写一个抖音App——基于FFmpeg的极简视频播放器GitHub地址
2.8K0
从零开始仿写一个抖音App——音视频开篇GitHub地址
2.3K0
IjkPlayer初始化过程
2K0
我的非线性视频编辑器MiaoVideoCut(1) --- 视频基础知识及环境搭建
1.2K0
​FFmpeg 开发(15):学习如何使用 FFmpeg 打造一个自己的通用播放器?
1.2K0
刷抖音上瘾后,决定探究如果做一款类似抖音短视频app
2.5K2
从零开始仿写一个抖音App——app架构更新与网络层定制
1.5K0
鸿蒙NEXT版仿抖音快手App的视频播放组件
2190
短视频 SDK 开发 (一) 开发一款短视频 SDK 需要具备哪些知识?
1.9K0
从零开始写一个抖音App——开始一、写在前面二、项目概述三、尾巴
1.2K0
【Android 音视频开发:FFmpeg音视频编解码篇】三、Android FFmpeg视频解码播放
3.2K0
音视频面试题集锦第 15 期 | 编辑 SDK 架构 | 直播回声 | 播放器架构
3960
美摄iOS端短视频SDK视频编辑的流程及方法
2.1K0
相关推荐
【Android 音视频开发打怪升级:FFmpeg音视频编解码篇】六、FFmpeg简单合成MP4:视屏解封与重新封装
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档