gpt4 book ai didi

android - FFmpeg:无法在 Android Q 上使用文件描述符进行搜索

转载 作者:行者123 更新时间:2023-12-03 13:25:45 27 4
gpt4 key购买 nike

鉴于公共(public)文件路径在具有范围存储的 Android Q 中通常不可用,我试图弄清楚如何使我的 FFmpeg 音频解码器与文件描述符一起工作,而不会将文件复制到我的应用程序的私有(private)目录中。

我们可以使用 Android Q privacy changes 中描述的方法轻松获取文件描述符。 , 并且可以使用 Passing a native fd int to FFMPEG from openable URI 中描述的管道协议(protocol)打开文件描述符.但是,使用 av_seek_frame 无法搜索结果。并且使用 AVFormatContext 的 duration 成员也无法获得持续时间.

有没有办法使用 FFmpeg 查找文件描述符并检索持续时间?

最佳答案

it is possible to open the file descriptor using the pipe protocol as described



我很好奇为什么有必要通过管道协议(protocol)打开文件描述符?
sView player自定义打开文件描述符 AVIO上下文 ,这是可搜索的,至少在较旧的测试版本的 Android 上是可搜索的。这是使用自定义 AVIOContext 打开 AVFormatContext 的伪代码。
    int aFileDescriptor = myResMgr->openFileDescriptor(theFileToLoad);
AVFormatContext* aFormatCtx = avformat_alloc_context();
StAVIOContext myAvioContext;
if(!myAvioContext.openFromDescriptor(aFileDescriptor, "rb")) {
// error
}

aFormatCtx->pb = myAvioContext.getAvioContext();
int avErrCode = avformat_open_input(&aFormatCtx, theFileToLoad, NULL, NULL);

下面是提取简化的 StAVIOFileContext 类定义的尝试。
//! Wrapper over AVIOContext for passing the custom I/O.
class StAVIOContext {
public:
//! Main constructor.
StAVIOContext() {
const int aBufferSize = 32768;
unsigned char* aBufferIO = (unsigned char* )av_malloc(aBufferSize + AV_INPUT_BUFFER_PADDING_SIZE);
AVIOContext* myAvioCtx = avio_alloc_context (aBufferIO, aBufferSize, 0, this, readCallback, writeCallback, seekCallback);
}

//! Destructor.
virtual ~StAVIOContext() {
close();
if (myAvioCtx != NULL) { av_free (myAvioCtx); }
}

//! Close the file.
void close() {
if(myFile != NULL) {
fclose(myFile);
myFile = NULL;
}
}

//! Associate a stream with a file that was previously opened for low-level I/O.
//! The associated file will be automatically closed on destruction.
bool openFromDescriptor(int theFD, const char* theMode) {
close();
#ifdef _WIN32
myFile = ::_fdopen(theFD, theMode);
#else
myFile = ::fdopen(theFD, theMode);
#endif
return myFile != NULL;
}

//! Access AVIO context.
AVIOContext* getAvioContext() const { return myAvioCtx; }

public:

//! Virtual method for reading the data.
virtual int read (uint8_t* theBuf,
int theBufSize) {
if(myFile == NULL) { return -1; }

int aNbRead = (int )::fread(theBuf, 1, theBufSize, myFile);
if(aNbRead == 0 && feof(myFile) != 0) { return AVERROR_EOF; }
return aNbRead;
}

//! Virtual method for writing the data.
virtual int write (uint8_t* theBuf,
int theBufSize) {
if(myFile == NULL) { return -1; }
return (int )::fwrite(theBuf, 1, theBufSize, myFile);
}

//! Virtual method for seeking to new position.
virtual int64_t seek (int64_t theOffset,
int theWhence) {
if(theWhence == AVSEEK_SIZE || myFile == NULL) { return -1; }
#ifdef _WIN32
bool isOk = ::_fseeki64(myFile, theOffset, theWhence) == 0;
#else
bool isOk = ::fseeko(myFile, theOffset, theWhence) == 0;
#endif
if(!isOk) { return -1; }
#ifdef _WIN32
return ::_ftelli64(myFile);
#else
return ::ftello(myFile);
#endif
}

private:
//! Callback for reading the data.
static int readCallback(void* theOpaque,
uint8_t* theBuf,
int theBufSize) {
return theOpaque != NULL
? ((StAVIOContext* )theOpaque)->read(theBuf, theBufSize)
: 0;
}

//! Callback for writing the data.
static int writeCallback(void* theOpaque,
uint8_t* theBuf,
int theBufSize) {
return theOpaque != NULL
? ((StAVIOContext* )theOpaque)->write(theBuf, theBufSize)
: 0;
}

//! Callback for seeking to new position.
static int64_t seekCallback(void* theOpaque,
int64_t theOffset,
int theWhence) {
return theOpaque != NULL
? ((StAVIOContext* )theOpaque)->seek(theOffset, theWhence)
: -1;
}

protected:
AVIOContext* myAvioCtx;
FILE* myFile;
};

关于android - FFmpeg:无法在 Android Q 上使用文件描述符进行搜索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57445600/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com