【音视频】ijkplayer引入Android项目

本文详细介绍了如何在Android项目中集成ijkplayer,包括环境搭建、配置、编译过程及最终测试播放等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【ijkplayer】引入Android项目(基于k0.8.8)

编译准备

git(Mac自带)、yasm(brew install yasm)、Android sdk(Android studio 默认)、ndk(r14b)、并配置环境变量

ndk 环境变量

(android-ndk-r14b)

export ANDROID_SDK=/Users/inke219223m/Library/Android/sdk/platform-tools
export ANDROID_NDK=/Volumes/Victory/dev/android-ndk-r14b

export PATH=$PATH:$ANDROID_SDK
export PATH=$PATH:$ANDROID_NDK
## mac环境需要配置下面亮项
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-linux-perf"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-bzlib"

M1 芯片配置ndk-build

#!/bin/sh
# 原来的注释掉
#DIR="$(cd "$(dirname "$0")" && pwd)"
#$DIR/build/ndk-build "$@"

# M1 build
DIR="$(cd "$(dirname "$0")" && pwd)"
arch -x86_64 /bin/bash $DIR/build/ndk-build "$@"

ijk 项目下载和拉取 fmpeg 代码

# clone项目
git clone https://github.com/Bilibili/ijkplayer.git

# 进入ijkplayer-android目录
cd ijkplayer

# 切换到最新代码分支
git checkout -B latest k0.8.8

# 会检查下载ffmpeg代码 
./init-android.sh

#初始化openSSL(使ijk编译后支持https)
./init-android-openssl.sh

编译前选择你的配置

官方库说明中提供了三种配置支持,每个sh脚本里有对应的配置信息,包含支持编码格式、流媒体协议类型等,如下截取一些decoders,enable标识支持该格式,disable则标识不支持。

支持解码格式

./configure --list-decoders

export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-decoders"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-decoder=aac"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-decoder=aac_latm"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-decoder=flv"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-decoder=h264"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-decoder=mp3*"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-decoder=vp6f"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-decoder=flac"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-decoder=hevc"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-decoder=vp8"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-decoder=vp9"

选择配置文件,ln -s 命令标识软连接,module.sh可以直接获取module-default.sh的配置

#If you prefer more codec/format
cd config
rm module.sh
ln -s module-default.sh module.sh

#If you prefer less codec/format for smaller binary size (include hevc function)
cd config
rm module.sh
ln -s module-lite-hevc.sh module.sh

#If you prefer less codec/format for smaller binary size (by default)
cd config
rm module.sh
ln -s module-lite.sh module.sh

编译

本次编译的是 Android 项目,所以先 cd 到 android/contrib 下 执行清除命令,然后编译对于的 so 库,all 标识编译所有架构的 so,想编译 armv7a 架构则将 all 替换成 armv7a

./compile-openssl.sh clean #清除
./compile-ffmpeg.sh clean  #清除
./compile-openssl.sh all   #编译
./compile-ffmpeg.sh all    #编译

生成 ijkplayer 对应架构 so 文件(all 同上输入对应架构则生成对应架构动态链接库),动态链接库生成路径如下图所示(路径示例:ijkplayer-android/android/ijkplayer/ijkplayer-armv7a/src/main/libs/armeabi-v7a)

注意本步骤需要同意不受信任软件权限,具体参考地址

# 注意回到android 路径下
cd ..
# 执行脚步生成so 文件
./compile-ijk.sh all

到此 ijkplayer 编译完成,如果播放器之前逻辑已经写好,则直接替换项目中对应的动态链接库文件就行

使用

项目导入

首先新建一个 ijkplayerdemo 工程, 将文件夹的文件 ijkplayer/android/ijkplayer 目录下的 tool 初始化工程脚本 gradle 文件复制到刚新穿件的项目根目录,然后在根项目的 build.gradle 中加入统一版本 ext 配置,相当于一个 map,方便导入 library 统一引入配置。

在这里插入图片描述

ext {

    compileSdkVersion = 30
    buildToolsVersion = "30.0.0"

    targetSdkVersion = 30

    versionCode = 800800
    versionName = "0.8.8"
}

导入 ijkplayer-example

-这个项目,他本身是一个可运行的项目,并且依赖前面编译好的各个版本动态链接库 library,将其变为library
则修改该模块 build.gradle 将 apply plugin: ‘com.android.application’ 改为 apply plugin: ‘com.android.library’。

ijkplayer-example 的清单文件还设置了启动的 Activity过滤器,将其删除

<intent-filter>
    <action android:name="android.intent.action.MAIN" />

    <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

各个CPU架构动态链接库 library 合并,简化项目依赖

在这里插入图片描述

CMakeLists.txt

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html

# Sets the minimum version of CMake required to build the native library.

# 指定 cmake 的最小版本
cmake_minimum_required(VERSION 3.10.2)

# 打印日志
message("当前CMake的路径是:${CMAKE_SOURCE_DIR}")
message("当前 CMAKE_ANDROID_ARCH_ABI 的路径是:${CMAKE_ANDROID_ARCH_ABI}")

# Log目录设置
IF (${CMAKE_HOST_SYSTEM_NAME} MATCHES "Windows")
    ADD_DEFINITIONS(-DWindows)
ELSE (${CMAKE_HOST_SYSTEM_NAME} MATCHES "Linux")
    ADD_DEFINITIONS(-DLinux)
ENDIF ()

# Declares and names the project.

# 设置项目名称
project("mediaandroid")

# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.

# 批量引入源文件
file(GLOB allCpp *.cpp)


aux_source_directory( src SRC_LIST )

include_directories( ${CMAKE_SOURCE_DIR}/inc )

# 加入cpp源文件
add_library( # Sets the name of the library.
        mediaandroid

        # Sets the library as a shared library.
        SHARED

        # Provides a relative path to your source file(s).
        #native-lib.cpp # 替换  ${allCpp} 批量导入文件
        ${allCpp}

        ${SRC_LIST}
        )


# 导入静态库
add_library(test_a STATIC IMPORTED)

# 开始真正的导入
set_target_properties(test_a PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libtest.a)

# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.

# 只能找系统的
find_library( # Sets the name of the path variable.
        log-lib

        # Specifies the name of the NDK library that
        # you want CMake to locate.
        log)

message("当前的log路径在哪里啊 >>>>>>>>>>>>>>>>> ${log-lib}")

# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.

#开始链接指定的库
target_link_libraries( # Specifies the target library.
        mediaandroid
        android
        GLESv3
        # Links the target library to the log library
        # included in the NDK.
        ${log-lib}
        )

处理依赖报错

ijkplayer-example依赖的包版本比较低,应该更改为我们对于版本support包,需要将ijkplayer-example的一些报错的类正确导包,和ijkplayer-java中一样,在ijkplayer-example目录下新建gradle.properties 文件并加入项目配置

POM_NAME=ijkplayer-example
POM_ARTIFACT_ID=ijkplayer-example
POM_PACKAGING=aar

ijkplayer-example 的 build.gardle 中productFlavors 配置删除

坑还是比较多的,不要着急,谷歌还是都能帮忙解决,注意关键字摄取,搞定完就能运行展示了,源码还需自己去理解

将ijkplayer-example依赖到主项目工程

    implementation fileTree(dir: "libs", include: ["*.jar"])

    implementation 'androidx.appcompat:appcompat:1.4.1'
    implementation 'com.google.android.material:material:1.6.0'
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'

    //第三方
    implementation 'tv.danmaku.ijk.media:ijkplayer-java:0.8.8'
    implementation 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.8.8'
    //导入子模块
    implementation project(path: ':ijkplayer-example')

编译通过项目结构

在这里插入图片描述

测试播放

package cn.com.codingce.mediaandroid.activity.ijk;

import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.widget.EditText;
import android.widget.TableLayout;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.AppCompatButton;

import cn.com.codingce.mediaandroid.R;
import tv.danmaku.ijk.media.example.application.Settings;
import tv.danmaku.ijk.media.example.widget.media.AndroidMediaController;
import tv.danmaku.ijk.media.example.widget.media.IjkVideoView;
import tv.danmaku.ijk.media.player.IjkMediaPlayer;

/**
 * 使用 ijkplayer  demo 提供的  IjkVideoView
 *
 * @author 24607
 */
public class IjkPlayer extends AppCompatActivity {

    private static final String TAG = "IjkPlayerActivity";

    String mVideoPath1 = "https://www.apple.com/105/media/us/iphone-x/2017/01df5b43-28e4-4848-bf20-490c34a926a7/films/feature/iphone-x-feature-tpl-cc-us-20170912_1920x1080h.mp4";

    private Settings settings;
    private AndroidMediaController mAndroidMediaController;
    IjkVideoView mVideoView;
    EditText editVideoPath;
    AppCompatButton btplay;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_ijk_player);

        settings = new Settings(this);
        mAndroidMediaController = new AndroidMediaController(this, false);
        IjkMediaPlayer.loadLibrariesOnce(null);
        IjkMediaPlayer.native_profileBegin("libijkplayer.so");

        mVideoView = findViewById(R.id.mVideoView);
        mVideoView.setMediaController(mAndroidMediaController);
        TableLayout videoMsg = new TableLayout(this);
        mVideoView.setHudView(videoMsg);
        editVideoPath = findViewById(R.id.editVideoPath);
        editVideoPath.setText(mVideoPath1);

        btplay = findViewById(R.id.btplay);
        btplay.setOnClickListener(view -> {
            if (TextUtils.isEmpty(editVideoPath.getText())) {
                Toast.makeText(this, "视频地址不能为空", Toast.LENGTH_LONG).show();
            } else {
                mVideoView.setVideoURI(Uri.parse(editVideoPath.getText().toString().trim()));
                mVideoView.start();
            }
        });
    }

    @Override
    protected void onDestroy() {
        try {
            super.onDestroy();
            mVideoView.stopPlayback();
            mVideoView.release(true);
            mVideoView.stopBackgroundPlay();
            IjkMediaPlayer.native_profileEnd();
        } catch (Exception e) {
            Log.e(TAG, "onDestroy Exception" + e.getMessage());
        }
    }
}

效果

在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

后端码匠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值