我正在使用Google提供的本机编解码器应用程序:(https://github.com/googlesamples/android-ndk/tree/master/native-codec)。 该应用程序有一个文件夹(资产),其中包含一些要播放的视频样本。 我的目的是从手机的内部存储器(即/sdcard/filename.mp4)中读取视频。 我将这两行添加到清单文件中,但这还没有解决问题。
<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;
}
当应用程序位于“资产”文件夹(即应用程序内)中时,该应用程序将成功播放视频。但是,当视频不在应用程序(内部/外部存储)之外时,该应用程序将停止工作。
是否有解决此问题的方法?
答案 0 :(得分:0)
除了添加存储权限外,用户还需要赋予手动权限。
出于测试目的,您可以转到“设置”->“应用程序”->“应用程序”->“权限”->“启用存储权限”。那应该工作正常。
出于生产目的,您应该通过对话寻求许可。有很多教程。