首页 > 其他分享 >跨平台xamarin.Android 开发之 :适配各架构(X86_64 、 X86、arm64-v8a、 armeabi-v7a )FFmpeg注册

跨平台xamarin.Android 开发之 :适配各架构(X86_64 、 X86、arm64-v8a、 armeabi-v7a )FFmpeg注册

时间:2023-08-13 15:34:35浏览次数:39  
标签:X86 lib 适配 v8a 跨平台 arm64 var Android

从事Windows,项目探索预研跨平台开发,对Android 只知道有X86_64 、 X86、arm64-v8a、  armeabi-v7a这么个东西其他空白。编译入手采用Xamarin.Android 开发。

通过摸索。在Xamarin.Android中使用FFmpeg 编解码,需要获取源码编译成对应Android 架构的so动态库,如何编译不在此处讨论,稍后补一篇专门对编译成对应Android 架构的so动态库讲解

1 需要在Android 中获取我们存放好的第三方.so 动态,在Android 中有这么一个文件夹 Assets,并将库生成操作改成AndroidAsset。

那么在代码当中我们就可以使用Android.App.Application.Context.Assets.Open(FileName)读取

 注:上面有一个区别,在X86_64 架构中,使用FFmpeg的动态库不需要"libc++_shared.so",因为系统自带。在ARM 中就需要在官网当中去下载对应32、64 的"libc++_shared.so"。

2 x64_64 下使用注册FFmpeg动态库,动态库的注册实现,此处不加以讲解稍后在博客中针对展开讲解

        /// <summary>
        /// 注册FFMPEG 
        /// </summary>
        /// <param name="ffmpegAndroidDlls"></param>
        private void InitFFmpeg()
        {

          //安卓依赖动态库
           Var _ffmpegAndroidDlls = new List<string>
           {
            "libavcodec.so.60",
            "libavdevice.so.60",
            "libavfilter.so.9",
            "libavformat.so.60",
            "libavutil.so.58",
            "libswresample.so.4",
            "libswscale.so.7"
            };

            //无论在Release还是Debug环境下
            string assemblyPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
            foreach (var ffmpegDll in ffmpegAndroidDlls)
            {
                var assemblyDirectoryDll = System.IO.Path.Combine(assemblyPath, ffmpegDll);
                using var inputStream = Android.App.Application.Context.Assets.Open($"{cpuArchitecture}/{ffmpegDll}");
                using var outputStream = new FileStream(assemblyDirectoryDll, FileMode.Create, FileAccess.Write);
                inputStream.CopyTo(outputStream);
            }
            //设置库路径
            if (!Directory.Exists(assemblyPath))
            {
                throw new DirectoryNotFoundException("FFMPEG 动态库路径不存在!");
            }
            FFmpegWrapper.RegisterFFmpeg(assemblyPath);
        }

3 X86_64调用上面注册即可。针对ARM 架构情况,就需要添加"libc++_shared.so"了。

 /// <summary>
        /// 注册FFMPEG 
        /// </summary>
        /// <param name="ffmpegAndroidDlls"></param>
        private void InitFFmpeg()
        {
          //安卓依赖动态库
           Var _ffmpegAndroidDlls = new List<string>
           {
            "libavcodec.so.60",
            "libavdevice.so.60",
            "libavfilter.so.9",
            "libavformat.so.60",
            "libavutil.so.58",
            "libswresample.so.4",
            "libswscale.so.7"
            };

            var cpuArchitecture = Android.OS.Build.CpuAbi;
            Debug.WriteLine($"当前Android Cpu架构: {cpuArchitecture}");
            if (cpuArchitecture.Equals("arm64-v8a") || cpuArchitecture.Equals("armeabi-v7a"))
            {
                ffmpegAndroidDlls.Add("libc++_shared.so");
            }

            //无论在Release还是Debug环境下
            string assemblyPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
            foreach (var ffmpegDll in ffmpegAndroidDlls)
            {
                var assemblyDirectoryDll = System.IO.Path.Combine(assemblyPath, ffmpegDll);
                using var inputStream = Android.App.Application.Context.Assets.Open($"{cpuArchitecture}/{ffmpegDll}");
                using var outputStream = new FileStream(assemblyDirectoryDll, FileMode.Create, FileAccess.Write);
                inputStream.CopyTo(outputStream);
            }
            //设置库路径
            if (!Directory.Exists(assemblyPath))
            {
                throw new DirectoryNotFoundException("FFMPEG 动态库路径不存在!");
            }
            FFmpegWrapper.RegisterFFmpeg(assemblyPath);
        }

4   【一落千妆】信心满满,在同事的最新Android手机上注册测试也通过了。后来同事给了一部2019年的老Android 10. 测试挂了

异常: [linker] library "/data/user/0/com.companyname.screenshareandroid/files/libavutil.so.58" ("/data/data/com.companyname.screenshareandroid/files/libavutil.so.58") needed or dlopened by "(unknown)" is not accessible for the namespace: [name="(anonymous)", ld_library_paths="", default_library_paths="/data/app/com.companyname.screenshareandroid-cTWv_NzZPbV7XkZ9G2wXbg==/lib/arm64:/data/app/com.companyname.screenshareandroid-cTWv_NzZPbV7XkZ9G2wXbg==/base.apk!/lib/arm64-v8a", permitted_paths=""]

这一下整不会了。然后请教Android 应用,Android 应用同事表示没见过,接着请教Android 系统,Android 系统同事表示也没见过。这个就尴尬了,没见过也正正常,毕竟我们使用C# xamarin 对Android 开发,不是原生的Android 应用开发。现在的问题是怎么处理。

5  查找资料,查看Xamarin 官方文档, 这一句 default_library_paths="/data/app/com.companyname.screenshareandroid-cTWv_NzZPbV7XkZ9G2wXbg==/lib/arm64:/data/app/com.companyname.screenshareandroid-cTWv_NzZPbV7XkZ9G2wXbg==/base.apk!/lib/arm64-v8a" 很重要。意思是在查找动态库的默认路径是 虚拟路径"/data/app/com.companyname.screenshareandroid-cTWv_NzZPbV7XkZ9G2wXbg==/lib/arm64:/data/app/com.companyname.screenshareandroid-cTWv_NzZPbV7XkZ9G2wXbg==/base.apk!/lib/arm64-v8a"。这个虚拟路径是什么? 就是Apk的内部路径/lib/arm64-v8a。好找到这个信息就好办了。

6  解决上面问题,通过查阅文档知道在Android 下添加jniLibs文件夹,然后添加对应架构的文件夹目录,把动态库放到对应架构目录下面,生成操作设置成AndroidNativeLibrary

或则修改Android.csproj

<ItemGroup>
<AndroidNativeLibrary Include="jniLibs\arm64-v8a\libavcodec.so.60"/>
    <AndroidNativeLibrary Include="jniLibs\arm64-v8a\libavdevice.so.60" />
    <AndroidNativeLibrary Include="jniLibs\arm64-v8a\libavfilter.so.9" />
    <AndroidNativeLibrary Include="jniLibs\arm64-v8a\libavformat.so.60" />
    <AndroidNativeLibrary Include="jniLibs\arm64-v8a\libavutil.so.58" />
    <AndroidNativeLibrary Include="jniLibs\arm64-v8a\libc++_shared.so" />
    <AndroidNativeLibrary Include="jniLibs\arm64-v8a\libswresample.so.4" />
    <AndroidNativeLibrary Include="jniLibs\arm64-v8a\libswscale.so.7" />
    <AndroidNativeLibrary Include="jniLibs\armeabi-v7a\libavcodec.so.60" />
    <AndroidNativeLibrary Include="jniLibs\armeabi-v7a\libavdevice.so.60" />
    <AndroidNativeLibrary Include="jniLibs\armeabi-v7a\libavfilter.so.9" />
    <AndroidNativeLibrary Include="jniLibs\armeabi-v7a\libavformat.so.60" />
    <AndroidNativeLibrary Include="jniLibs\armeabi-v7a\libavutil.so.58" />
    <AndroidNativeLibrary Include="jniLibs\armeabi-v7a\libc++_shared.so" />
    <AndroidNativeLibrary Include="jniLibs\armeabi-v7a\libswresample.so.4" />
    <AndroidNativeLibrary Include="jniLibs\armeabi-v7a\libswscale.so.7" />
    <AndroidNativeLibrary Include="jniLibs\x86_64\libavcodec.so.60" />
    <AndroidNativeLibrary Include="jniLibs\x86_64\libavdevice.so.60" />
    <AndroidNativeLibrary Include="jniLibs\x86_64\libavfilter.so.9" />
    <AndroidNativeLibrary Include="jniLibs\x86_64\libavformat.so.60" />
    <AndroidNativeLibrary Include="jniLibs\x86_64\libavutil.so.58" />
    <AndroidNativeLibrary Include="jniLibs\x86_64\libswresample.so.4" />
    <AndroidNativeLibrary Include="jniLibs\x86_64\libswscale.so.7" />
</ItemGroup>

注: X86_64 、arm64-v8a、  armeabi-v7a 编解码有细微差异:体现在内存分配以及取指操作,有时间再补一篇针对讲解

标签:X86,lib,适配,v8a,跨平台,arm64,var,Android
From: https://www.cnblogs.com/terryK/p/17626627.html

相关文章

  • 对话音视频牛哥:如何设计功能齐全的跨平台低延迟RTMP播放器
    开发背景2015年,我们在做移动单兵应急指挥项目的时候,推送端采用了RTMP方案,这在当时算是介入RTMP比较早的了,RTMP推送模块做好以后,我们找了市面上VLC还有Vitamio,来测试整体延迟,实际效果真的不尽人意,大家知道,应急指挥系统,除了稳定性外,对延迟有很高的要求,几秒钟(>3-5秒)的延迟,是我们接受不......
  • 小程序生成App:可跨平台开发的移动应用开发框架
    小程序生成App可以成为一种轻量低门槛的开发App的方式,但是需要根据具体情况进行选择。如果应用需要处理大量数据或需要进行复杂计算,或者需要实现原生特有的功能或交互效果,可能需要选择其他开发方式。在文章开始之前,我们看看目前市面上比较容易上手、低门槛开发App的框架和方式Rea......
  • Axure 9无法设置移动设备适配的解决方法
    虽然Axure9做了很多移动端的适配工作,移动端的设计体验也好了很多,但是只是在PC端预览有移动端的效果,在移动设备上浏览却没有自动适应屏幕的效果,而且也没有设置移动端的适配的入口而在Axure8中是有这个设置面板的,设置非常方便,如下:   那如何才能设置移动端适配呢,还是有办......
  • Android屏幕适配全攻略(最权威的官方适配指导)
    Android的屏幕适配一直以来都在折磨着我们这些开发者,本篇文章以Google的官方文档为基础,全面而深入的讲解了Android屏幕适配的原因、重要概念、解决方案及最佳实践,我相信如果你能认真的学习本文,对于Android的屏幕适配,你将有所收获! Android屏幕适配出现的原因重要概念屏幕尺寸屏幕......
  • vivo 场景下的 H5无障碍适配实践
    作者:vivo互联网前端团队-ZhangLi、DaiWenkuan随着信息无障碍的建设越来越受重视,开发人员在无障碍适配中也遇到了越来越多的挑战。本文是笔者在vivo开发H5项目做无障碍适配的实践总结。本文主要介绍了在前端项目中常用的无障碍手势和无障碍属性,并且结合具体的开发案例为开发......
  • 在x86构架中 时间片是如何实现的
     在x86架构(通常指的是基于Intel的x86指令集架构)中,时间片的实现通常涉及操作系统、中断机制和时钟硬件。以下是在x86架构中实现时间片的一般步骤:硬件时钟:在x86架构中,存在一个硬件时钟,通常称为计时器或时钟中断。这个时钟以固定的频率发出中断,比如每秒100次中......
  • warning: /var/cache/yum/x86_64/7/mysql57-community/packages/mysql-community-comm
    问题描述在我正确地安装好mysql包之后,再安装mysql,就出现了这么一个问题:就去疯狂百度找解决问题的方法!!!问题解决经过查找资料,才发现,原来是有GPG验证检查,只需要禁止GPG验证检查就行啦!也就是在安装mysql的语句后面,加上这样一个语句:--nogpgcheck总起来就是:yum-yinstallmys......
  • Android 12 适配之 "Android:exported"
    Android12适配之"Android:exported"将build.gradle中的targetSDKVersion和compileSdkVersion改为31,对应Android12build项目报错AppstargetingAndroid12andhigherarerequiredtospecifyanexplicitvalueforandroid:exportedwhenthecorrespondingc......
  • rider下载安装 一款.Net跨平台开发神器 安装指南
    rider下载安装一款.Net跨平台开发神器安装指南原文链接:https://baijiahao.baidu.com/s?id=1763943888509043020&wfr=spider&for=pc下载破解补丁后,解压得到,如下图:将上面图示的补丁的所属文件夹/jetbra复制电脑某个位置,小编这里放置到了默认的下载目录下(不推荐,自己选个D盘目......
  • STL迭代器适配器reverse_iterator剖析 #C++
    迭代器适配器(iteratoradapters)迭代器适配器是迭代器应用于迭代器的产物,包括insertiterator,reverseiterator和iostreamiterator。迭代器适配器本质是对容器或一般迭代器进行封装,以使其更加符合需求。reverse_iterator概述reverse_iterator可以将一般迭代器的行进方向进......