Android StageFrightMediaScanner源码解析

1. 简单介绍

Android中在StageFrightMediaScanner实现对多媒体文件的处理。


此外在StageFrightMediaScanner定义了支持的多媒体文件类型。
文件位置
frameworksavmedialibstagefrightStagefrightMediaScanner.cpp
编译目标
libstagefright.so

2. processFile

processFile并没有做什么处理。主要是调用processFileInternal。
另外能够看到在processFile中调用MediaScannerClient的beginFile和endFile方法,时间上google并没有实现beginFile和endFile方法。
(说实话Android5.0 真的非常烂,非常多功能根本就没有开发全然)

MediaScanResult StagefrightMediaScanner::processFile(
        const char *path, const char *mimeType,
        MediaScannerClient &client) {
    //MediaScannerClient根本就没有实现。所以不用关心
    client.setLocale(locale());
    client.beginFile();
    MediaScanResult result = processFileInternal(path, mimeType, client);
    client.endFile();
    return result;
}

3. processFileInternal

processFileInternal能够说是MediaScanner处理多媒体文件终于节点
在此函数中通过调用MediaMetadataRetriever获取多媒体信息。


调用MediaMetadataRetriever获取媒体文件信息步骤例如以下:
(1) MediaMetadataRetriever.setDataSource(file)
(2) MediaMetadataRetriever.extractMetadata(key)

MediaScanResult StagefrightMediaScanner::processFileInternal(
        const char *path, const char * /* mimeType */,
        MediaScannerClient &client) {
    const char *extension = strrchr(path, '.');
    ///check file type 
    if (!extension) {
        return MEDIA_SCAN_RESULT_SKIPPED;
    }

    if (!FileHasAcceptableExtension(extension)) {
        return MEDIA_SCAN_RESULT_SKIPPED;
    }
    //----------------------------------------
    ///Init & setDataSource MediaMetadataRetriever
    sp<MediaMetadataRetriever> mRetriever(new MediaMetadataRetriever);

    int fd = open(path, O_RDONLY | O_LARGEFILE);
    status_t status;
    if (fd < 0) {
        // couldn't open it locally, maybe the media server can?
        status = mRetriever->setDataSource(NULL /* httpService */, path);
    } else {
        status = mRetriever->setDataSource(fd, 0, 0x7ffffffffffffffL);
        close(fd);
    }
    //----------------------------------------
    ///get MIMETYPE
    const char *value;
    if ((value = mRetriever->extractMetadata(
                    METADATA_KEY_MIMETYPE)) != NULL) {
        status = client.setMimeType(value);
        if (status) {
            return MEDIA_SCAN_RESULT_ERROR;
        }
    }
    //----------------------------------------
    .........
    ///get metadata
    for (size_t i = 0; i < kNumEntries; ++i) {
        const char *value;
        if ((value = mRetriever->extractMetadata(kKeyMap[i].key)) != NULL) {
            status = client.addStringTag(kKeyMap[i].tag, value);
            if (status != OK) {
                return MEDIA_SCAN_RESULT_ERROR;
            }
        }
    }

    return MEDIA_SCAN_RESULT_OK;
}
原文地址:https://www.cnblogs.com/yfceshi/p/7365750.html