无法使用谷歌使用 adb 提供的原生编解码器播放内部存储中的视频



我正在使用Google提供的本机编解码器应用程序:(https://github.com/googlesamples/android-ndk/tree/master/native-codec)。该应用程序有一个文件夹(资产),其中包含一些要播放的视频样本。我的目的是从手机的内部存储中读取视频(即/sdcard/filename.mp4)。我将这 2 行添加到清单文件中,但这还没有帮助解决问题。

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

我修改了代码以获取视频文件名作为 adb shell 给出的参数。这是代码:

    mSourceString = getIntent().getStringExtra("arg");
    if (!mCreated) {
        if (mSourceString != null) {
            mCreated = createStreamingMediaPlayer(getResources().getAssets(), mSourceString);
        }
    }
    if (mCreated) {
        mIsPlaying = !mIsPlaying;
        setPlayingStreamingMediaPlayer(mIsPlaying);
    }

读取视频文件名的方法的本机代码如下:

jboolean Java_com_example_mohammed_myapplication_MainActivity_createStreamingMediaPlayer(JNIEnv* env,                                                                                   jclass clazz, jobject assetMgr, jstring filename)
{
    LOGV("@@@ create");
    // convert Java string to UTF-8
    const char *utf8 = env->GetStringUTFChars(filename, NULL);
    LOGV("opening %s", utf8);
    off_t outStart, outLen;
    int fd = AAsset_openFileDescriptor(AAssetManager_open(AAssetManager_fromJava(env, assetMgr), utf8, 0),
                                       &outStart, &outLen);
    env->ReleaseStringUTFChars(filename, utf8);
    if (fd < 0) {
        LOGE("failed to open file: %s %d (%s)", utf8, fd, strerror(errno));
        return JNI_FALSE;
    }
    data.fd = fd;
    workerdata *d = &data;
    AMediaExtractor *ex = AMediaExtractor_new();
    media_status_t err = AMediaExtractor_setDataSourceFd(ex, d->fd,
                                                         static_cast<off64_t>(outStart),
                                                         static_cast<off64_t>(outLen));
    close(d->fd);
    if (err != AMEDIA_OK) {
        LOGV("setDataSource error: %d", err);
        return JNI_FALSE;
    }
    int numtracks = AMediaExtractor_getTrackCount(ex);
    AMediaCodec *codec = NULL;
    LOGV("input has %d tracks", numtracks);
    for (int i = 0; i < numtracks; i++) {
        AMediaFormat *format = AMediaExtractor_getTrackFormat(ex, i);
        const char *s = AMediaFormat_toString(format);
        LOGV("track %d format: %s", i, s);
        const char *mime;
        if (!AMediaFormat_getString(format, AMEDIAFORMAT_KEY_MIME, &mime)) {
            LOGV("no mime type");
            return JNI_FALSE;
        } else if (!strncmp(mime, "video/", 6)) {
            // Omitting most error handling for clarity.
            // Production code should check for errors.
            AMediaExtractor_selectTrack(ex, i);
            codec = AMediaCodec_createDecoderByType(mime);
            AMediaCodec_configure(codec, format, d->window, NULL, 0);
            d->ex = ex;
            d->codec = codec;
            d->renderstart = -1;
            d->sawInputEOS = false;
            d->sawOutputEOS = false;
            d->isPlaying = false;
            d->renderonce = true;
            AMediaCodec_start(codec);
        }
        AMediaFormat_delete(format);
    }
    mlooper = new mylooper();
    mlooper->post(kMsgCodecBuffer, d);
    return JNI_TRUE;
}

当视频位于"资产"文件夹中(即在应用程序内部)时,该应用程序可以成功播放视频。但是当视频在应用程序之外(内部/外部存储)时,应用程序将停止工作。

这个问题有解决方案吗?

除了添加存储权限外,用户还需要授予手动权限。

出于测试目的,您可以转到设置->应用->你的应用->权限->启用存储权限。那么应该可以正常工作。

出于生产目的,您应该通过对话请求许可。有很多教程可以做到这一点。

相关内容

最新更新