当前位置: 首页 > news >正文

短视频 SDK 开发 (一) 开发一款短视频 SDK 需要具备哪些知识?

前言

2020 年要属什么最火,肯定是短视频和直播带货了。我自己基本上每天晚上睡觉之前都会刷一会儿 douyin 短视频,不得不承认 douyin 的推荐算法是真 nb ,推荐的都是我的最爱 ???? 。那么 douyin 短视频这么 nb 我们可不可以自己模仿着也做一个? 想想都觉得难啊,但是还是可以模仿着做一个的。我们先来看一下效果,这只是第一个版本,具备的功能有限。后面会一直持续迭代下去!

那么,作为一个音视频零基础的人来说, 开发一款短视频 SDK 到底需要具备哪些知识呢? 下面就由我为大家介绍一翻(ps:以下学习路径仅代表个人观点)。

接下来的日子我准备从 0-1 写一个如何开发一款音视频编辑的 SDK 系列文章,下面是我的计划。

短视频 SDK 开发 (一) 开发一款短视频 SDK 需要具备哪些知识?

短视频 SDK 开发 (二) 短视频 SDK 架构设计

短视频 SDK 开发 (三) FFmpeg + OpenGL ES + OpenSL ES + soundtouch 实现音视频播放器

短视频 SDK 开发 (四) Camera + MediaCodec + OpenGL ES + OpenSL ES + FFmpeg MP4Muxer 实现音视频实时录制封装为 MP4

短视频 SDK 开发 (五) 滤镜、贴纸、水印实现

短视频 SDK 开发 (六) 美颜特效实现

短视频 SDK 开发 (七) 音视频剪辑实现

基础知识

1、你必须要有 「C/C++」 开发语言基础,可以看我之前写的文章

  • 音视频学习 (一) C 语言入门

  • 音视频学习 (二) C++ 语言入门

2、接下来就需要掌握 「JNI」 基础了

  • 音视频学习 (三) JNI 从入门到掌握

3、有了 「C/C++/JNI」 基础,你还要学会如何交叉编译 「FFmpeg」 等 C/C++ 库

  • 音视频学习 (四) 交叉编译动态库、静态库的入门学习

  • 音视频学习 (五) Shell 脚本入门

  • 音视频学习 (六) FFmpeg 4.2.2 交叉编译

4、有了以上的基础,那么就可以开始了解 音视频 的基础知识了

  • 雷神-视音频编解码技术零基础学习方法

  • 雷神-视音频数据处理入门:RGB、YUV像素数据处理

  • 雷神-视音频数据处理入门:PCM音频采样数据处理

  • 雷神-视音频数据处理入门:H.264视频码流解析

  • 雷神-视音频数据处理入门:AAC音频码流解析

  • 音视频学习 (七) 掌握音频基础知识并使用 AudioTrack、OpenSL ES 渲染 PCM 数据

  • 音视频学习 (八) 掌握视频基础知识并使用 OpenGL ES 2.0 渲染 YUV 数据

5、现在可以入手音视频 AAC 、H264 软硬编解码了

组件库对应关系
fdkaac_audio_encode_decodeLibfdk-aac 音频编解码
x264_video_encodeLibx264 视频编码
mediacodec_audio_encode_decodeAndroid MediaCodec AAC 硬编解码
mediacodec_video_encode_decodeAndroid MediaCodec H264 硬编解码
ffmpeg_audio_encode_decodeFFmpeg API 实现音频 AAC 软编解码
ffmpeg_video_encode_decodeFFmpeg API 实现视频 H264 软编解码
lame_ffmpeg_mp3_encode_decodeMP3 编解码
JavaAVPlayerJava API 实现音视频播放(mp3/mp4/pcm/yuv)
NativeAVPlayerNative 端实现音视频播放(PCM/YUV)
ffmpeg_muxer基于 h264,AAC 文件打包为 MP4

基础知识差不多就这些了,如果有落下的后面再补上

中级知识

1、FFmpeg + OpenGL ES + OpenSL ES + soundtouch 完成音视频播放

  • Google 官方的音视频播放库 -grafika

  • bilibili 官方开源的音视频播放库- ijkplayer

  • 当然也可以参考我自己的 AVEditor 音视频播放模块

2、OpenGL ES 渲染视频是必须要会的

  • NDK_OpenGLES_3_0

3、Camera + MediaCodec + OpenGL ES + OpenSL ES + FFmpeg MP4Muxer 实现音视频录制为 MP4 格式

  • camera_recorder

4、RTMP 推流实现

  • AVRtmpPushSDK

高级知识

1、音视频变速、变调录制

  • 音频-soundtouch

  • 视频修改时间戳即可达到变速录制

2、音视频录制实时滤镜实现

  • android-gpuimage

3、分段录制、水印、背景音

「分段录制:」 每次录制完成将录制的路径保存下来,最后将这些 MP4 的文件合并为一个 MP4 文件

「水印:」  拿着上一个视频处理的 纹理 ID ,在这基础上渲染一个 BItmap 即可

「背景音混音:」 可以参考如下实现代码

/**
 * 参考地址:https://www.shangmayuan.com/a/6daeefedbecb463f9dfce318.html
 * 归一算法:http://www.cppblog.com/jinq0123/archive/2007/10/31/35615.aspx
 * 能量值实现:https://www.jianshu.com/p/d3745dd23056
 * 实现原理:
 * 其实音频混音的核心原理就是将两个音频的原始byte数据进行叠加,
 * 很是简单的 + 起来,好比某个位置的数据是 1 而另外一个音频一样位置是 2 加起来就是3,
 * 这样就完成了音频的混音,固然这是最基础也是最垃圾的混音算法,咱们这里会介绍其中的一种混音算法,
 * 基本上能够达到商业使用的。那就是归一化混音算法。
 *
 *    C = A + B - A * B / (数据类型的最大值);
 *    byte数据就是
 *     C = A + B - A * B / 127;
 *     short数据就是
 *     C = A + B - A * B / 32767;
 *     //vol的取值范围 一般是小于10,大于0的,若是是0的话,就没有声音了,若是太大了就会出现杂音
 *     C = A * vol;
 *
 *
 *     混音算法总结:
 *     总结一下我对混音算法的学习,大概有以下几种方式:
 *      1. 直接加和
 *      2. 加和后再除以混音通道数,防止溢出
 *      3. 加和并箝位,如有溢出就设最大值
 *      4. 饱和处理,接近最大值时进行扭曲(“软件混音的实现”一文算法就是这类)
 *      5. 归一化处理,全部乘个系数,使幅值归一化。(只适用于文件)
 *      6. 衰减因子法,用衰减因子限制幅值[1]。
 */

extern "C"
JNIEXPORT jbyteArray JNICALL
Java_org_doubango_ngn_media_mixer_MultiAudioMixer_audioMix2(JNIEnv *env, jobject instance,
                                                            jbyteArray sourceA_,
                                                            jbyteArray sourceB_,
                                                            jbyteArray dst_, jfloat firstVol,
                                                            jfloat secondVol) {
    jbyte *sourceA = env->GetByteArrayElements(sourceA_, NULL);
    jbyte *sourceB = env->GetByteArrayElements(sourceB_, NULL);
    jbyte *dst = env->GetByteArrayElements(dst_, NULL);

    //归一化混音
    int aL = env->GetArrayLength(sourceA_);
    int bL = env->GetArrayLength(sourceB_);
    //除以通道数量
    int row = aL / 2;

    short sA[row];
    for (int i = 0; i < row; ++i) {
        sA[i] = (short) ((sourceA[i * 2] & 0xff) | (sourceA[i * 2 + 1] & 0xff) << 8);
    }

    short sB[row];
    for (int i = 0; i < row; ++i) {
        sB[i] = (short) ((sourceB[i * 2] & 0xff) | (sourceB[i * 2 + 1] & 0xff) << 8);
    }

    short result[row];
    for (int i = 0; i < row; ++i) {
        int a = (int) (sA[i] * firstVol);
        int b = (int) (sB[i] * secondVol);
        if (a < 0 && b < 0) {
            int i1 = a + b - a * b / (-32768);
            if (i1 > 32768) {
                result[i] = 32767;
            } else if (i1 < -32768) {
                result[i] = -32768;
            } else {
                result[i] = (short) i1;
            }
        } else if (a > 0 && b > 0) {
            int i1 = a + b - a * b / 32767;
            if (i1 > 32767) {
                result[i] = 32767;
            } else if (i1 < -32768) {
                result[i] = -32768;
            } else {
                result[i] = (short) i1;
            }
        } else {
            int i1 = a + b;
            if (i1 > 32767) {
                result[i] = 32767;
            } else if (i1 < -32768) {
                result[i] = -32768;
            } else {
                result[i] = (short) i1;
            }
        }
    }
    for (int i = 0; i < row; ++i) {
        dst[i * 2 + 1] = (jbyte) ((result[i] & 0xFF00) >> 8);
        dst[i * 2] = (jbyte) (result[i] & 0x00FF);
    }

    jbyteArray result1 = env->NewByteArray(aL);
    env->SetByteArrayRegion(result1, 0, aL, dst);

    env->ReleaseByteArrayElements(sourceA_, sourceA, 0);
    env->ReleaseByteArrayElements(sourceB_, sourceB, 0);
    env->ReleaseByteArrayElements(dst_, dst, 0);
    return result1;
}

5、人脸识别-特效

  • 可以使用 OpenCV 来做人脸识别,拿到人脸特征点位,最后利用这些点位用 OpenGL 绘制绘制出来就行了。

6、音视频剪辑技术

书籍推荐

  • <<音视频进阶指南>>

  • <<OpenGL ES 3.0 编程指南>>

  • <<学习 OpenCV 3 中文版>>

总结

目前能想到的从 0-1 开发一款短视频 SDK 需要具备的知识大概就是这些。其实学习这些知识相对而言时间成本都比较高,因为每一个知识点基本上都是一个独立的,就拿 OpenGL 来说, 要学这门知识基本上肯定是要按 月 为单位来计算。当然不要看着学习成本高,就直接放弃了,一般来说高投入肯定会有高回报的。好了,短视频入门开发就介绍到这里了。下面推荐一个目前我自己开源的零基础音视频进阶路线项目, 有需要的可以关注 star 一波 AVSample

贴一张进阶路线图

短视频 SDK 项目有更新都会提交到此处 AVEditor (ps:目前只是一个半成品,功能尚未开发完成)

相关文章:

  • 滴滴AR实景导航背后的技术
  • 国庆假期归来,音视频继续搞起,WebRTC送书活动来啦~~~
  • 「字节跳动直播研发团队」是如何每天护航百万直播间的?
  • FFmpeg代码架构
  • 播放器性能优化干货
  • WebRTC 送书活动获奖人员名单公布啦~~~
  • 为什么那些学好音视频的人,能够月薪50K+?
  • 绝密计划:我在阿里打黑工
  • 带你通过字节跳动面试---操作系统复习
  • Android 中通过 FFmpeg 命令对音视频编辑处理(已开源)
  • 花里胡哨的3D翻页卡片,隔壁产品都馋哭了
  • 从Chrome小恐龙游戏学习2D游戏制作
  • UML科普文,一篇文章掌握14种UML图
  • 黑白键上的字节跳动:全球最大钢琴MIDI数据集背后的故事
  • 当当福利,音视频开发囤书活动!
  • CAP 一致性协议及应用解析
  • CentOS 7 防火墙操作
  • ES6 ...操作符
  • JAVA并发编程--1.基础概念
  • Kibana配置logstash,报表一体化
  • SQLServer之创建显式事务
  • Vue全家桶实现一个Web App
  • Web Storage相关
  • 得到一个数组中任意X个元素的所有组合 即C(n,m)
  • 简单实现一个textarea自适应高度
  • 如何设计一个比特币钱包服务
  • 如何正确配置 Ubuntu 14.04 服务器?
  • 使用 5W1H 写出高可读的 Git Commit Message
  • 原生js练习题---第五课
  • 你对linux中grep命令知道多少?
  • AI算硅基生命吗,为什么?
  • #设计模式#4.6 Flyweight(享元) 对象结构型模式
  • #我与Java虚拟机的故事#连载17:我的Java技术水平有了一个本质的提升
  • (0)Nginx 功能特性
  • (1)(1.8) MSP(MultiWii 串行协议)(4.1 版)
  • (Matalb分类预测)GA-BP遗传算法优化BP神经网络的多维分类预测
  • (附源码)spring boot智能服药提醒app 毕业设计 102151
  • (黑客游戏)HackTheGame1.21 过关攻略
  • (算法)Travel Information Center
  • .Net core 6.0 升8.0
  • .Net 高效开发之不可错过的实用工具
  • .net6 webapi log4net完整配置使用流程
  • .NET的微型Web框架 Nancy
  • @Pointcut 使用
  • @RequestMapping处理请求异常
  • [ C++ ] STL---仿函数与priority_queue
  • [2008][note]腔内级联拉曼发射的,二极管泵浦多频调Q laser——
  • [2023-年度总结]凡是过往,皆为序章
  • [AI]文心一言爆火的同时,ChatGPT带来了这么多的开源项目你了解吗
  • [Android] Implementation vs API dependency
  • [android学习笔记]学习jni编程
  • [FC][常见Mapper IRQ研究]
  • [github全教程]github版本控制最全教学------- 大厂找工作面试必备!
  • [POJ2446] Chessboard(二分图最大匹配-匈牙利算法)
  • [Python进阶] 获取计算机相关信息:Psutil