修改ffmpeg支持文件描述符,以适配android10沙箱机制

问题背景

android10默认执行文件沙箱机制,native层代码失去了通过文件路径访问公共媒体文件的权限。当时可通过android:requestLegacyExternalStorage="true" 来兼容,设置这个标志后依然可以通过路径访问。

估计是谷歌考虑到不太合理,android11改回来了,android11的真机上native层恢复可以通过路径访问公共媒体文件,不需要设置android:requestLegacyExternalStorage="true"

但是蛋疼的是,发的目标android11的包还是有可能被android10真机下载,所以android:requestLegacyExternalStorage="true"这个还是得设置以免android10的用户出错。

另外,发包带上android:requestLegacyExternalStorage="true"这个标志还会收到谷歌的警告。

基于以上麻烦,决定试试使用文件描述符来代替路径。在java层通过MediaStore的权限打开媒体文件,取得文件描述符,然后把文件描述符传到native层,native层使用文件描述符来读写文件。这样就可以把android:requestLegacyExternalStorage="true"甩掉。

解决思路

ffmpeg只支持路径参数的api,我们需要想办法让他支持文件描述符(FD)。

一种方法是重写新的支持FD的api,这样修改太大,最后放弃这种做法。

看了一下ffmpeg内部,关于文件操作的部分,在AVformat模块里面。刚好使用的文件api不是fopen这套,是系统io这套(open,read),也就是说文件描述符只要传进去就能直接用。

想了一番后,决定不需要大改,把FD有效传进去就行了。而FD是个int值,可以转成字符串送进去,在里面再恢复int,这样利用现有的路径就能带进去。

为了区别真正的路径,我们选个假路径作为沟通的“密码”就行了。

"fileDescriptorkey/" + FD

例如在外面avformat_open_input传 “fileDescriptorkey/123” 进去,里面检测到fileDescriptorkey这串“密码”,就知道这不是普通路径,是带货来的,后面跟的123就是FD值。

接下来就是修改ffmpeg里面的代码,识别到这个key就另外处理就行了。

ffmpeg修改

跟踪一下代码,确认里面关于路径逻辑修改后,不影响整个解码流程走向,确实可行。
而最后定位到只要修改avformat模块下的file.c文件就可以打到我要的效果。这个文件刚好负责全部的普通文件处理,没有什么耦合性,容易修改。
改两个函数,添加一个函数,就行,如下

static int getfdfs(const char *str,char *ptr)
{
   
	while (*str != '.' && *str != 0) {
   
		*ptr = *str;
		ptr++;
		str++;
	}
	*ptr = 0;
	return 0;
}

static int file_check(URLContext *h, int mask)
{
   
    int ret = 0;
    const char *filename = h->filename;
    av_strstart(filename, "file:", &filename);

	char *fds;
	char fdss[64] = {
    0 };
	if (av_strstart(filename, 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值