librtmp开源库与android平台编译记录

librtmp库API介绍及其结构概述 文章目录librtmp库API介绍及其结构概述1、librtmp API的使用1.1 librtmp API的使用流程1.2 librtmp的实例1.3 librtmp API详解1.3.1 librtmp中的chunk和message1.3.2 RTMP基本API1.3.3 设置RTMP的属性1.3.4 连接服务器1.3.5 创建rtmp流1.3.6 对RTMP流的操作1.3.6.1 控制类API1.3.6.2 查询类API1.3.6.3 读写类API2. librtmp数据流的读写流程2.1 传输层 阅读详情

一、编写目的

为了记录编译librtmp开源库过程遇到的问题,帮助后来人提供参考,希望本文能为大家提供参考。

二、简介(官方介绍)

The Real-Time Messaging Protocol (RTMP) is used for streaming multimedia content across a TCP/IP network. This API provides most client functions and a few server functions needed to support RTMP, RTMP tunneled in HTTP (RTMPT), encrypted RTMP (RTMPE), RTMP over SSL/TLS (RTMPS) and tunneled variants of these encrypted types (RTMPTE, RTMPTS). The basic RTMP specification has been published by Adobe but this API was reverse-engineered without use of the Adobe specification. As such, it may deviate from any published specifications but it usually duplicates the actual behavior of the original Adobe clients.

三、编译步骤

1、下载源码

可以从以下两个仓库下载源码,目前使用master主分支

git clone https://github.com/shishuo365/librtmp.git
git clone https://github.com/LinChengChun/librtmp.git

2、安装Android NDK

为了开发支持android平台的库,所以需要下载google官方的NDK

https://developer.android.google.cn/ndk/downloads/index.html

3、 使用android ndk 提供脚本,允许自己定制一套工具链

cd android-ndk-r13b/build/tools/
./make-standalone-toolchain.sh --platform=android-14 --install-dir=/home/cclin/android-toolchain --force
----------------------------------------------------------------------------------------------------------------------------------------
Valid options (defaults are in brackets):
  --help                  Print this help.
  --verbose                Enable verbose mode.
  --dryrun                Unsupported.
  --toolchain=<name>      Specify toolchain name
  --use-llvm              No-op. Clang is always available.
  --stl=<name>            Specify C++ STL [gnustl]
  --arch=<name>            Specify target architecture    默认是 arm,可以指定其他指令架构
  --abis=<list>            No-op. Derived from --arch or --toolchain.
  --ndk-dir=<path>        Unsupported.
  --package-dir=<path>    Place package file in <path> [/tmp/ndk-cclin]    如果不指定安装目录,默认生成一个压缩包,路径在/tmp/ndk-cclin
  --install-dir=<path>    Don't create package, install files to <path> instead.    指定 工具链安装目录
  --dryrun                Unsupported.
  --platform=<name>        Specify target Android platform/API level. [android-9]    指定哪个平台/API 版本
  --force                  Remove existing install directory.    强制覆盖上一次生成的文件

4、获得工具链后,就可以编译支持android平台的librtmp库了

  • 根据上一步生成的工具链,修改 librtmp 目录下的Makefile和tools/compile-librtmp-android.sh
diff --git a/Makefile b/Makefile
index 1597948..a761d8d 100644
--- a/Makefile
+++ b/Makefile
@@ -72,7 +72,7 @@ SOINST_yes=install_so
SO_DEF=$(SODEF_$(SHARED))
SO_LIB=$(SOLIB_$(SHARED))
SO_INST=$(SOINST_$(SHARED))
-
+XLDFLAGS=-llog
DEF=-DRTMPDUMP_VERSION=\"$(VERSION)\" $(CRYPTO_DEF) $(XDEF)
OPT=-O2
CFLAGS=-Wall $(ARCH_CFLAGS) $(XCFLAGS) $(INC) $(DEF) $(OPT) $(SO_DEF)
diff --git a/tools/compile-librtmp-android.sh b/tools/compile-librtmp-android.sh
old mode 100644
new mode 100755
index 032bfab..a56faa7
--- a/tools/compile-librtmp-android.sh
+++ b/tools/compile-librtmp-android.sh
@@ -8,17 +8,19 @@ if [ -z "$RTMP_ARCH" ]; then
fi

# replace this path to your android NDK standalone toolchain ptah.
-RTMP_TOOLCHAIN_PATH=/Users/shishuo/Documents/app/Android-NDK-Toolchain
+#RTMP_TOOLCHAIN_PATH=/Users/shishuo/Documents/app/Android-NDK-Toolchain
+RTMP_TOOLCHAIN_PATH=/home/cclin/android-toolchain/bin/
RTMP_BUILD_ROOT=`pwd`
RTMP_BIN_ROOT=$RTMP_BUILD_ROOT/bin
RTMP_ARCH_DIR=
cd ..

compile_armv7a() {
-      export CC=$RTMP_TOOLCHAIN_PATH/arm/bin/arm-linux-androideabi-gcc
-      export LD=$RTMP_TOOLCHAIN_PATH/arm/bin/arm-linux-androideabi-ld
-      export AR=$RTMP_TOOLCHAIN_PATH/arm/bin/arm-linux-androideabi-ar
-      export ARCH_CFLAGS=-march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=softfp -mthumb
+      export CC=$RTMP_TOOLCHAIN_PATH/arm-linux-androideabi-gcc
+      export LD=$RTMP_TOOLCHAIN_PATH/arm-linux-androideabi-ld
+      export AR=$RTMP_TOOLCHAIN_PATH/arm-linux-androideabi-ar
+      export ARCH_CFLAGS=-march=armv7-a
+    #-mfpu=vfpv3-d16 -mfloat-abi=softfp -mthumb
        make clean
        make all
}
@@ -94,6 +96,7 @@ release_librtmp() {
        cp -f http.h    $RTMP_BIN_ROOT/$RTMP_ARCH_DIR/include/librtmp
        cp -f log.h    $RTMP_BIN_ROOT/$RTMP_ARCH_DIR/include/librtmp
        cp -f rtmp.h    $RTMP_BIN_ROOT/$RTMP_ARCH_DIR/include/librtmp
+    #cp -f librtmp.so.1 $RTMP_BIN_ROOT/$RTMP_ARCH_DIR/librtmp.so
}

if [ "$RTMP_ARCH" = "armv7a" ]; then
@@ -137,4 +140,4 @@ elif [ "$RTMP_ARCH" = "all" ]; then
else
    echo "unknown architecture $RTMP_ARCH";
    exit 1
-fi
\ No newline at end of file
+fi
  • 跳转到 librtmp/tools 目录运行编译脚本,即可开始编译
./compile-librtmp-android.sh armv7a    // 由于只编译armv7a架构的,因此只修改了compile-librtmp-android.sh中对应的编译器有效路径,如果需要编译其他架构需要重新生成对应工具链,重新配置对应架构下面编译器的有效路径

5、生成的文件

librtmp/tools/bin/armeabi-v7a$cp ../../../librtmp.so.1 librtmp.so
librtmp/tools/bin/armeabi-v7a$ ls -R
.:
include  lib  librtmp.so

./include:
librtmp

./include/librtmp:
amf.h  http.h  log.h  rtmp.h

./lib:
librtmp.a

6、在AS新建一个工程用于使用librtmp库

  • 项目结构
    这里写图片描述
  • Android.mk
# Android.mk for rtmp

LOCAL_PATH := $(call my-dir)

# rtmp library
include $(CLEAR_VARS)
LOCAL_MODULE := rtmp
LOCAL_SRC_FILES := librtmp.so
include $(PREBUILT_SHARED_LIBRARY)
#include $(PREBUILT_STATIC_LIBRARY)


# Program
include $(CLEAR_VARS)
LOCAL_MODULE := nativeRtmp
LOCAL_SRC_FILES := nativeRtmp.c
LOCAL_C_INCLUDES += $(LOCAL_PATH)/include
LOCAL_LDLIBS := -llog -lz
LOCAL_SHARED_LIBRARIES := rtmp
include $(BUILD_SHARED_LIBRARY)
-----------------------------------------------------------------上面是引用librtmp.so动态库脚本,下面是引用librtmp.a静态库脚本------------
# Android.mk for rtmp

LOCAL_PATH := $(call my-dir)

# rtmp library
include $(CLEAR_VARS)
LOCAL_MODULE := rtmp
#LOCAL_SRC_FILES := librtmp.so
#include $(PREBUILT_SHARED_LIBRARY)
LOCAL_SRC_FILES := librtmp.a
include $(PREBUILT_STATIC_LIBRARY)


# Program
include $(CLEAR_VARS)
LOCAL_MODULE := nativeRtmp
LOCAL_SRC_FILES := nativeRtmp.c
LOCAL_C_INCLUDES += $(LOCAL_PATH)/include
LOCAL_LDLIBS := -llog -lz
LOCAL_STATIC_LIBRARIES := rtmp
#LOCAL_SHARED_LIBRARIES := rtmp
include $(BUILD_SHARED_LIBRARY)
  • Application.mk
#APP_ABI := all
#APP_ABI := armeabi armeabi-v7a x86
APP_ABI :=armeabi-v7a
  • rtmpJNI.java
package org.src.rtmp_get;

/**
* Created by Administrator on 2015/12/4.
*/
public class rtmpJNI {
    public native void rtmpDeInit();

    public native void rtmpInit(String rtmpUrl);

    static {
        System.loadLibrary("rtmp"); // 如果编译脚本引用librtmp.so库,需要添加该句;如果引用librtmp.a,需要注释该句;引用动态库时,native调用RTMP_Close时会出现进程崩溃;引用静态库时,运行正常,所以建议引用静态库。
        System.loadLibrary("nativeRtmp");
    }

}
  • MainActivity.java
package org.src.rtmp_get;

import android.app.Activity;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends Activity {

    private rtmpJNI  mRtmpClient ;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mRtmpClient = new rtmpJNI();
        mRtmpClient.rtmpInit("rtmp://192.168.1.116");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mRtmpClient.rtmpDeInit();
    }
}
  • nativeRtmp.c
//
// Created by Administrator on 2015/12/4.
//
#include <jni.h>
#include <assert.h>
#include <string.h>
#include "include/librtmp/rtmp.h"
#include <sys/types.h>
#include <android/log.h>


#define LOG_TAG "NativeRTMP"
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__))
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))
static const char *ClassName = "org/src/rtmp_get/rtmpJNI";


char* pubRtmpUrl;
RTMP *pubRtmp; //rtmp


void send_pkt(char* buf, int buflen, int type, unsigned int timestamp)
{
    int ret;
    RTMPPacket rtmp_pakt;
    RTMPPacket_Reset(&rtmp_pakt);
    RTMPPacket_Alloc(&rtmp_pakt, buflen);
    rtmp_pakt.m_packetType = type;
    rtmp_pakt.m_nBodySize = buflen;
    rtmp_pakt.m_nTimeStamp = timestamp;
    rtmp_pakt.m_nChannel = 4;
    rtmp_pakt.m_headerType = RTMP_PACKET_SIZE_LARGE;
    rtmp_pakt.m_nInfoField2 = pubRtmp->m_stream_id;
    memcpy(rtmp_pakt.m_body, buf, buflen);
    ret = RTMP_SendPacket(pubRtmp, &rtmp_pakt, 0);
    RTMPPacket_Free(&rtmp_pakt);
}

void my_Native_rtmpInit(JNIEnv *env, jobject jobj,jstring jRtmpUrl){

    const char* rtmpUrl = (*env)->GetStringUTFChars(env, jRtmpUrl, 0);
    pubRtmpUrl = malloc(strlen(rtmpUrl) + 1);
    memset(pubRtmpUrl, 0, strlen(rtmpUrl) + 1);
    strcpy(pubRtmpUrl, rtmpUrl);

    pubRtmp = RTMP_Alloc();
    RTMP_Init(pubRtmp);
    LOGI("RTMP_Init %s", pubRtmpUrl);
    if (!RTMP_SetupURL(pubRtmp, pubRtmpUrl)) {
        LOGE("RTMP_SetupURL error");
        return;
    }
    if (!RTMP_Connect(pubRtmp, NULL) ) {
        LOGE("RTMP_Connect error");
        return;
    }
  /* if (!RTMP_ConnectStream(pubRtmp, 0)) {
        LOGE("RTMP_ConnectStream  error");
        return;
    }*/
    LOGI("RTMP Connect  ok");
    send_pkt("aa", 20, RTMP_PACKET_TYPE_AUDIO,  20);

}

void my_Native_rtmpDeInit(JNIEnv *env, jobject jobj)
{
    if (RTMP_IsConnected(pubRtmp)) {
        RTMP_Close(pubRtmp);
    }
    RTMP_Free(pubRtmp);
    free(pubRtmpUrl);
}

static JNINativeMethod METHODS[]={
        {"rtmpInit","(Ljava/lang/String;)V",(void *)my_Native_rtmpInit},
        {"rtmpDeInit","()V",(void *)my_Native_rtmpDeInit},
};


JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
    int retVal = -1;
    JNIEnv *env;
    if ( (*vm)->GetEnv(vm,(void **) &env, JNI_VERSION_1_4) == JNI_OK  ) {
    jclass clazz = (*env)->FindClass(env,ClassName);
    if (clazz != NULL) {
    if ((*env)->RegisterNatives(env,clazz, METHODS,sizeof(METHODS) / sizeof(METHODS[0])) >= 0) {
    retVal = JNI_VERSION_1_4;
    }else{
    LOGI("RegisterNatives Subprocess.create method failed!");
    }
    (*env)->DeleteLocalRef(env,clazz);
    }else{
    LOGI("className not found!");
    }
    }
    return retVal;
}

JNIEXPORT void JNICALL JNI_OnUnload(JavaVM* vm, void* reserved)
{
}

四、总结

根据以上记录,librtmp库最好在linux平台编译(mingw编译不成功);编译成功后,新建一个工程测试一下librtmp库的功能,前提是具有RTMP服务器,便于通信。当然,也可以使用附件的工程来测试;本文主要是记录 librtmp编译以及在APP中的应用。后续再分析librtmp、rtmp协议相关知识点。^-^

附件rtmpDumpDemo
链接:https://pan.baidu.com/s/1nvl9inn 密码:plhb

librtmp优化 阅读详情

相关推荐

【流媒体】基于libRTMP的H264推流器

前面记录了RTMP协议相关的内容,本文记录如何使用libRTMP库进行推流,推流的内容是本地H264码流,向RTMP服务器(nginx)进行推流,并且在传输之后使用ffplay进行拉流播放,主要参考了雷博的实现方式,但根据自己的理解进行了代码简化,加上了自己的理解和注释。在修改过程中,直接使用了雷博提供的libRTMP库,没有自己编译,这一点可能得后续再看看。

weixin_42877471的博客 2264

基于librtmp的安卓小项目:投屏摄像头和手机拼屏幕视频:推流rtmp到服务器上并显示在其它设备上(比如电脑或者其它直播平台)

基于librtmp的安卓小项目:投屏摄像头视频:推流rtmp到服务器上并显示在其它设备上(比如电脑或者其它直播平台)

m0_62602360的博客 1476

kettle从入门到精通 第九十二课 ETL之kettle 使用Kettle的Carte对外发布读写接口

场景:使用kettle实现将查询结果返回给客户端,也就是说kettle暴露查询接口供外围系统调用。前提必须是使用carte服务才可以提供接口供外部系统调用。具体实操方法如下:1、设计转换根据具体需求设计转换,主要用到的步骤有获取变量(从请求参数中获取变量)、json输入(解析入参),json 输出将结果转换为json格式输出到客户端。如下图所示:2、接收参数使用获取变量步骤来接收接口请求参数,变量通过${}方法进行获取,如下图${PARAM}则是获取PARAM参数,将参数赋值为req字段。

zhangjin1222的博客 954

Android 使用librtmp推流

最近一个发现一个android手机推流的一个开源项目,视频采用H264编码、音频采用ACC编码、传输采用Rtmp协议,下面是github地址: https://github.com/blueberryCoder/LiveStream

SK的博客 3288

FileZilla Server 1.2.0 TLS证书过期问题

FileZilla Server TLS证书过期后重新生成

Wigle的备忘录 7526

告别复杂模型:用UFLD算法5分钟搞定车道线检测(附Python代码)

本文介绍了UFLD(Ultra Fast Lane Detection)算法在车道线检测中的高效应用,仅需5行核心代码即可实现实时检测,特别适合边缘计算设备。通过对比传统方法,UFLD在推理速度、模型大小和硬件需求上具有显著优势,是深度学习领域轻量级解决方案的典范。

weixin_27872611的博客 287

android x86 vmware tools_Mac交叉编译Android平台的librtmp库

1.下载源码git clone git://git.ffmpeg.org/rtmpdump2.ndk生成toolchain/Users/arikes/Third/Android/ndk/android-ndk-r10e/build/tools/make-standalone-toolchain.sh --platform=android-19 --install-dir=/Users/arikes...

weixin_39757122的博客 253

实现敌人跟随玩家。(Unity)

首先和玩家设置一模一样,给敌人添加一个刚体,设置一个碰撞器,并设置一个触发器。然后在对场景里面的组件添加导航网格代理并且进行bake烘焙,那样的话敌人就可以在进行烘焙的位置进行移动。创建脚本,并且挂载脚本到敌人的组件上,用代码进行实现效果,并且要挂载目标对象。

weixin_57813136的博客 1869

librtmp项目推荐

librtmp项目推荐 项目基础介绍和主要编程语言 librtmp是一个开源的RTMP(Real-Time Messaging Protocol)库,主要用于Android和iOS平台。该项目的主要编程语言是C,同时也包含一些Shell脚本用于构建和配置。librtmp是基于RTMP协议的实现,广泛应用于实时流媒体传输和直播领域。 项目核心功能 librtmp的核心功能包括: RTMP协议支持:...

gitblog_01045的博客 445

面经-2023-联发科MTK-数字芯片设计

面经-2023-联发科MTK-数字芯片设计

w0shishabi的博客 2944

大疆A型板使用经验分享(二)——A型板原理图和引脚图

一.原理图 二.引脚图

weixin_43361652的博客 7681

直播技术初探

一、搭建直播流接收的服务器1)采用nginx服务器安装:https://www.cnblogs.com/Leesttee/p/8193389.html搭建rtmp服务器:https://blog.youkuaiyun.com/boonya/article/details/78663675(主要是配置nginx-win-rtmp.conf文件) rtmp { ...

weixin_34329187的博客 149

单光子雪崩二极管(SPAD):原理、极高增益机制与微光探测解析

本文系统阐述了单光子雪崩二极管(SPAD)的工作原理及其在弱光探测中的应用。SPAD通过工作在盖革模式下的碰撞离化效应实现单光子探测,其核心机理包括:1)采用p+-n-n+结构实现高电场分布;2)通过雪崩倍增过程获得10^6量级增益;3)采用主动/被动淬灭机制实现快速恢复。文章详细分析了SPAD的关键性能参数(如光子探测效率、暗计数率等)及其在量子通信、激光雷达等领域的应用优势,揭示了该器件在极微弱光信号探测中的独特价值。

Fun_LiDAR的博客 1043

librtmp学习

学习雷博士的文章环境:Ubuntu 16.04.7ffmpeg-6.1。

langzi113的专栏 2232

Fiori Elements 从入门到精通开发教程的文章目录

Fiori Elements 开发技术相对 SAP 其他历史悠久,发展成熟的开发技术来说,是一个新事物。正因如此,迄今为止国内深入讲解 Fiori Elements 应用的中文材料几乎没有。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 4759

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Android移植librtmp

一、前言 为了让android能够使用librtmp,我们需要下载它的源码并使用交叉编译工具编译成可以供android使用的库文件。我在网上参考了一些别人移植的文章,但到自己移植的时候缺踩了许多坑。还好今天终于移植成功了,特此总结一下。 二、流程 我看了一下网上的资料大概流程都是: 1、从ndk中提出一个交叉编译工具链,并设置环境变量,供我们编译使用。 2、因为librtmp需要依赖ssl

BlueBerry的专栏 5870

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

librtmp源码详解

实时流协议(Real-TimeMessaging Protocol,RTMP)是用于互联网上传输视音频数据的网络协议。本API提供了支持RTMP, RTMPT,RTMPE,RTMPS及以上几种协议的变种(RTMPTE, RTMPTS)协议所需的大部分客户端功能以及少许的服务器功能。尽管Adobe公司已经公布了RTMP协议规范(RTMP specification),可是本工程并非经过Adobe的协议规范而是经过逆向工程的方式完成的。...

xuerongdeng的专栏 1945

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Android 使用librtmp推流【视频采集模块】

视频采集

SK的博客 1058

探索Android LibRTMP项目:实时视频流传输的新里程碑

探索Android LibRTMP项目:实时视频流传输的新里程碑 去发现同类优质开源项目:https://gitcode.com/ 项目简介 是一个为Android平台定制的开源库,它实现了librtmp协议,使开发者能够轻松地将实时视频流推送到RTMP服务器,实现高效、低延迟的直播功能。该项目由中际浩开发并维护,旨在为移动应用开发提供强大的直播工具。 技术分析 LibRTMP协议 LibRTMP...

gitblog_00047的博客 544

ubuntu16.04//usr/local/lib/librtmp.so.1: undefined reference to `SSLv23_server_method@OPENSSL_1.0.0'

问题描述 在编译程序时,显示 /usr/bin/ld: warning: libssl.so.1.0.0, needed by //usr/local/lib/librtmp.so.1, not found (try using -rpath or -rpath-link) //usr/local/lib/librtmp.so.1: undefined reference to `SSL_CTX_...

weixin_45617478的博客 2345

LibRtmp-Client-for-Android 安装和配置指南

### 项目基础介绍 LibRtmp-Client-for-Android 是一个用于 Android 平台的 RTMP 客户端库。它可能是 Android 上最小的 RTMP 客户端之一,大小约为 60KB(胖版本约为 300KB)。该库通过 JNI 接口调用 librtmp 函数,支持多种 CPU 架构(如 arm、arm7、arm8、x86、x86-64、mips)。 ### 主要的编程语

gitblog_01278的博客 1318

【亲测免费】 Android Librtmp客户端技术文档

--- ## 安装指南 为了在您的Android项目中集成此Librtmp客户端,您需要按照以下步骤操作: 1. 打开您的Android Studio项目。 2. 转至`build.gradle`(Module: app)文件。 3. 在`dependencies`块中,添加以下依赖项: ```groovy dependencies { // 其他依赖...

gitblog_01272的博客 1355

使用librtmp推送AVC数据——Android端

http://blog.youkuaiyun.com/a992036795/article/details/54572335 版权声明:本文为博主原创文章,未经博主允许不得转载。 一、前言  本文要讲述的是将AVC(h264)数据推送到流媒体服务器。我的实现方法是:1先使用Android自带的API采集摄像头数据,然后进行h264编码。2、然后使用ndk开发将编码后的

STN_LCD的专栏 1045

android移植好的librtmp 2.4:为Android平台带来高效RTMP流媒体传输

android移植好的librtmp 2.4:为Android平台带来高效RTMP流媒体传输 【下载地址】android移植好的librtmp2.4 这个开源项目提供了经过移植的 librtmp 2.4 版本,专为 Android 平台优化。librtmp 是一个强大的 C 库,支持 RTMP 协议,广泛应用于流媒体传输...

gitblog_06702的博客 679

Android下编译librtmp库

Android NDK:https://download.youkuaiyun.com/download/tong5956/10678081 librtmp:这里有两个可选仓库 git clone https://github.com/shishuo365/librtmp.git git clone https://github.com/LinChengChun/librtmp.git 1、创建...

tong5956的专栏 1678

ijkplayer中使用librtmp (Android)

本文将从零开始详细讲述怎么在ijkplayer中添加使用librtmp

九尾狐狸的专栏 7790
上一篇: Android JNI模板与读取系统属性笔记
下一篇: Android不同系统版本的悬浮窗权限问题
艾特小王子
博客等级 码龄10年 6粉丝 17原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值