热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发笔记:Ubuntu编译ijkplayerso库并播放本地raw/assets文件

本文由编程笔记#小编为大家整理,主要介绍了Ubuntu编译ijkplayerso库并播放本地raw/assets文件相关的知识,希望对你有一定的参考价值。
本文由编程笔记#小编为大家整理,主要介绍了Ubuntu编译ijkplayer so库并播放本地raw/assets文件相关的知识,希望对你有一定的参考价值。






一,前期基础知识储备

1. ijkplayer 官方项目地址:https://github.com/Bilibili/ijkplayer

ijkplayer 是一个基于 ffmpeg 的轻量级 android/ios 视频播放器。实现了跨平台功能,API易于集成;编译配置可裁剪,方便控制安装包大小;支持硬件加速解码,更加省电。可以通过编译来实现更多格式的支持,可以说只要是 ffmpeg 支持的格式 ijkplayer 就支持。

2. Ubuntu 下载地址:https://cn.ubuntu.com/

官方中文名“友帮拓”,也有班图、乌班图、乌斑兔、乌帮图、笨兔等非官方译名。

Ubuntu是一个以桌面应用为主的Linux操作系统,是世界上最流行的Linux系统之一。

1)虚拟机下体验:

运行虚拟机,在虚拟机中获得更完整的体验。下载安装虚拟机。成功安装后运行虚拟机,选择菜单栏中的“管理”→“导入虚拟电脑”选项,将所下载体验镜像导入虚拟机,最后运行Ubuntu虚拟机,这样就可以获得比较真实的体验。在虚拟机中几乎可以完成所有操作,没有限制。

小白菜Windows10系统安装Linux(ubuntu)虚拟机超详细教程

本文,选择这一种方式在Windows10系统中安装Ubutntu。

2)制作Live USB
还有一-种获得真实体验的途径,即制作LiveUSB,它比虚拟机更进一步,直接跑在真实的硬件环境中,更快且更加节省资源。

Ubuntu18.04/20.04完整新手安装教程


二,上手编译

具体步骤如下:

1. 配置环境 (windows)

1)安装 VMware 虚拟机并安装 Ubuntu 系统;

2)下载NDK SDK,上传至Ubuntu;

3) 配置好NDK SDK环境变量;

4) 安装git、yasm 和 make;

2. 正式编译 - 参考 ijkplayer 中编译 Android的步骤 Build Android

3. 项目中使用编译好的so库


1. 配置环境

1)安装 VMware 虚拟机并安装 Ubuntu 系统

小白菜Windows10系统安装Linux(ubuntu)虚拟机超详细教程

2)下载NDK SDK,上传至Ubuntu

下载好 Linux 版本的的 Android SDK 和 NDK,这里选择的分别是 android-sdk_r24.4.1-linux.tgz 和 android-ndk-r10e-linux-x86_64.zip,下载后可以使用如下命令解压文件:



tar -xvf android-sdk_r24.4.1-linux.tar


unzip android-ndk-r10e-linux-x86_64.zip


切记不要将 NDK 目录放在虚拟机的共享目录下,为保证编译顺利进行应将 NDK 目录放在 Ubuntu 的系统目录,也就是 /home/用户名 下面的目录。

3) 配置好NDK SDK环境变量

在 Ubuntu 下的 /home/用户名/ ,按 Ctrl+h 查看 .bashrc 文件并配置 SDK 和 NDK 环境变量,参考如下:

NDK=/home/chinstyle/android/android-ndk-r10e
export NDK
ADB=/home/chinstyle/android/android-sdk-linux/platform-tools
export ADB
# ANDROID_NDK和ANDROID_SDK路径
ANDROID_NDK=/home/chinstyle/android/android-ndk-r10e
export ANDROID_NDK
ANDROID_SDK=/home/chinstyle/android/android-sdk-linux
export ANDROID_SDK
# 加入到PATH路径
PATH=${PATH}:${NDK}:${ADB}:${ANDROID_NDK}:${ANDROID_SDK}

配置完成后保存并关闭 .bashrc,打开 Terminal 输入 ndk-build -v 查看 ndk 是否配置成功,运行日志如下则配置成功:

Ctrl + Alt + T - 打开终端。

若是提示 ndk -build 权限不够,则需要给权限,建议给整个ndk文件夹权限。

chmod -R 777 文件夹
参数-R是递归的意思
777表示开放所有权限

4) 安装git、yasm 和 make

sudo apt-get update
sudo apt install git
sudo apt install yasm
sudo apt install make

使用 git --version 和 make -v 查看 git 和 make 工具是否安装成功,成功则显示对应版本号,参考如下:

chinstyle@chinstyle-virtual-machine:~$ git --version
git version 2.25.1
chinstyle@chinstyle-virtual-machine:~$ make -v
GNU Make 4.2.1
为 x86_64-pc-linux-gnu 编译
Copyright (C) 1988-2016 Free Software Foundation, Inc.
许可证:GPLv3+:GNU 通用公共许可证第 3 版或更新版本html>。
本软件是自由软件:您可以自由修改和重新发布它。
在法律允许的范围内没有其他保证。

2. 正式编译

参考 ijkplayer 中编译 Android的步骤 Build Android



//clone ijkplayer源码
git clone https://github.com/Bilibili/ijkplayer.git ijkplayer
cd ijkplayer
git checkout -B latest k0.8.8
//使用更轻量的module-lite.sh
cd ijkplayer/config
rm module.sh
ln -s module-lite module.sh
//下载ffmpeg源码 - 耗时较长
cd ijkplayer
./init-android.sh
//编译arm64 ffmpeg
./compile-ffmpeg.sh clean
./compile-ffmpeg.sh arm64 // 若是使用all 则编译所有架构的so
//编译ijkplayer,生成arm64 so文件
cd ijkplayer/android
./compile-ijk.sh arm64 // 若是使用all 则编译所有架构的so


提几点注意事项:

1)git checkout -B latest k0.8.8 - 要切换到此分支,要不然后续使用C++方法会缺失;

2)ln -s module-lite module.sh - ijkplayer 提供了3个版本的编译脚本配置



module-default.sh:默认,如果你喜欢更多类型可以用这个;
module-lite-hevc.sh:如果您更喜欢较小的二进制大小的编解码器/格式(包括hevc功能)
module-lite.sh:如果您更喜欢较小的二进制大小的编解码器/格式(默认情况下)


区别:lite.sh相当于在default.sh的基础上,关闭了所有的解码器等全体操作,然后按照需求,比如开启对应的解码器。具体可以打开编译脚本查看。你可以打开module.sh自行进行修改。

3)compile-ffmpeg.sh arm64 & compile-ijk.sh arm64 :这里只编译arm64位的so库,这样编译时间短点。若是需要编译所有架构的so,则把arm64换成all就行了。

编译时间较长,需要耐心等待。

4)编译结果 - 生成对应的so库

编译的ijkplayer 项目整体如下:


3. 使用编译好的so库

1)添加ijkplayer依赖

//ijkplayer player
implementation 'tv.danmaku.ijk.media:ijkplayer-java:0.8.8'
//ijkplayer so文件
implementation 'tv.danmaku.ijk.media:ijkplayer-arm64:0.8.8'

这是直接使用ijkplayer提供的依赖,可以直接使用。

我们这里选择使用自己刚刚编译好的so。把“ijkplayer-java” 和 “ijkplayer-arm64” 2个项目全部拷贝至我们的项目中,以项目依赖的方式直接使用。

setting.gradle
include ':app', 'ijkplayer-arm64','ijkplayer-java'
build.gradle
// implementation 'tv.danmaku.ijk.media:ijkplayer-java:0.8.8'
// implementation 'tv.danmaku.ijk.media:ijkplayer-arm64:0.8.8'
api project(path: ':ijkplayer-arm64')
api project(path: ':ijkplayer-java')

2)播放raw/assets下的音乐文件

// 播放raw下的音乐
public void onIjkPlayRaw(View view) {
//实例化播放内核
tv.danmaku.ijk.media.player.IjkMediaPlayer ijkPlayer = new tv.danmaku.ijk.media.player.IjkMediaPlayer();
//获得播放源访问入口
AssetFileDescriptor afd = getResources().openRawResourceFd(R.raw.ynew); // 注意这里的区别
//构建IjkPlayer能识别的IMediaDataSource,下面的RawDataSourceProvider实现了IMediaDataSource接口
RawDataSourceProvider sourceProvider = new RawDataSourceProvider(afd);
//给IjkPlayer设置播放源
ijkPlayer.setDataSource(sourceProvider);
//设置准备就绪状态监听
ijkPlayer .setOnPreparedListener((IMediaPlayer.OnPreparedListener) mp -> {
// 开始播放
ijkPlayer.start();
});
//准备播放
ijkPlayer.prepareAsync();
}
// 播放assets下的音乐
public void onIjkPlayAsset(View view) {
tv.danmaku.ijk.media.player.IjkMediaPlayer ijkPlayer = new tv.danmaku.ijk.media.player.IjkMediaPlayer();
AssetManager am = getAssets();
try {
AssetFileDescriptor afd = am.openFd("intput.aac");
RawDataSourceProvider sourceProvider = new RawDataSourceProvider(afd);
ijkPlayer.setDataSource(sourceProvider);
} catch (IOException e) {
e.printStackTrace();
}
ijkPlayer .setOnPreparedListener((IMediaPlayer.OnPreparedListener) mp -> {
ijkPlayer.start();
});
ijkPlayer.prepareAsync();
}

// ijkplayer播放本地文件的入口
public class RawDataSourceProvider implements IMediaDataSource {
private AssetFileDescriptor mDescriptor;
private byte[] mMediaBytes;
public RawDataSourceProvider(AssetFileDescriptor descriptor) {
this.mDescriptor = descriptor;
}
@Override
public int readAt(long position, byte[] buffer, int offset, int size) throws IOException {
if(position + 1 >= mMediaBytes.length){
return -1;
}
int length;
if(position + size length = size;
}else{
length = (int) (mMediaBytes.length - position);
if(length > buffer.length)
length = buffer.length ;
length--;
}
System.arraycopy(mMediaBytes, (int) position, buffer, offset, length);
return length;
}
@Override
public long getSize() throws IOException {
long length = mDescriptor.getLength();
if(mMediaBytes == null){
InputStream inputStream = mDescriptor.createInputStream();
mMediaBytes = readBytes(inputStream);
}
return length;
}
@Override
public void close() throws IOException {
if(mDescriptor != null)
mDescriptor.close();
mDescriptor = null;
mMediaBytes = null;
}
private byte[] readBytes(InputStream inputStream) throws IOException {
ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int len = 0;
while ((len = inputStream.read(buffer)) != -1) {
byteBuffer.write(buffer, 0, len);
}
return byteBuffer.toByteArray();
}
public static RawDataSourceProvider create(Context context, Uri uri){
try {
AssetFileDescriptor fileDescriptor = context.getContentResolver().openAssetFileDescriptor(uri, "r");
return new RawDataSourceProvider(fileDescriptor);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return null;
}
}

至此,我们编译ijkplayer就完成了。


参考文章

《如何正确编译ijkplayer》

《ijkplayer编译so库真没那么难》

《一步步带你编译哔哩哔哩ijkPlayer》

《播放Raw/Assets音视频方法总结》




推荐阅读
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 本文介绍了在Ubuntu下制作deb安装包及离线安装包的方法,通过备份/var/cache/apt/archives文件夹中的安装包,并建立包列表及依赖信息文件,添加本地源,更新源列表,可以在没有网络的情况下更新系统。同时提供了命令示例和资源下载链接。 ... [详细]
  • 本文详细介绍了在Centos7上部署安装zabbix5.0的步骤和注意事项,包括准备工作、获取所需的yum源、关闭防火墙和SELINUX等。提供了一步一步的操作指南,帮助读者顺利完成安装过程。 ... [详细]
  • 本文内容为asp.net微信公众平台开发的目录汇总,包括数据库设计、多层架构框架搭建和入口实现、微信消息封装及反射赋值、关注事件、用户记录、回复文本消息、图文消息、服务搭建(接入)、自定义菜单等。同时提供了示例代码和相关的后台管理功能。内容涵盖了多个方面,适合综合运用。 ... [详细]
  • Monkey《大话移动——Android与iOS应用测试指南》的预购信息发布啦!
    Monkey《大话移动——Android与iOS应用测试指南》的预购信息已经发布,可以在京东和当当网进行预购。感谢几位大牛给出的书评,并呼吁大家的支持。明天京东的链接也将发布。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 【Windows】实现微信双开或多开的方法及步骤详解
    本文介绍了在Windows系统下实现微信双开或多开的方法,通过安装微信电脑版、复制微信程序启动路径、修改文本文件为bat文件等步骤,实现同时登录两个或多个微信的效果。相比于使用虚拟机的方法,本方法更简单易行,适用于任何电脑,并且不会消耗过多系统资源。详细步骤和原理解释请参考本文内容。 ... [详细]
  • 本文讲述了作者通过点火测试男友的性格和承受能力,以考验婚姻问题。作者故意不安慰男友并再次点火,观察他的反应。这个行为是善意的玩人,旨在了解男友的性格和避免婚姻问题。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
author-avatar
牧羊人2602903895
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有