Glion移动视频服务不适用于本地存储在android设备上的媒体文件?

Glion移动视频服务不适用于本地存储在android设备上的媒体文件?,android,gluon-mobile,Android,Gluon Mobile,在我的应用程序中,我想使用Gluon移动视频服务播放本地存储在android设备上的URL或文件中的视频。 这适用于URL,但(在我的环境中)它不适用于存储在android设备上的文件, e、 g./sdcard/DCIM/tmp/1834.mp4. 日志显示 V/MediaPlayerService(2431): Create new media retriever from pid 10868 W/AndroidVideoService(10868): Invalid video file:

在我的应用程序中,我想使用Gluon移动视频服务播放本地存储在android设备上的URL或文件中的视频。 这适用于URL,但(在我的环境中)它不适用于存储在android设备上的文件, e、 g.
/sdcard/DCIM/tmp/1834.mp4.

日志显示

V/MediaPlayerService(2431): Create new media retriever from pid 10868
W/AndroidVideoService(10868): Invalid video file: /sdcard/DCIM/tmp/1834.mp4
V/MediaPlayer(10868): resetDrmState:  mDrmInfo=null mDrmProvisioningThread=null mPrepareDrmInProgress=false mActiveDrmScheme=false
我可以用独立的Android视频播放器在那个位置播放文件

我还尝试以编程方式将文件复制到

  • StorageService.getPublicStorage(“电影”)
    (->
    /storage/simulated/0/Movies
    )或
  • StorageService.getPrivateStorage()
    /data/user/0/mypackage/files
加上“/tmp/”+“1834.mp4”

然后从那里通过应用程序播放,但LogCat消息再次显示

W/AndroidVideoService(...): Invalid video file ...
javadoc说

媒体文件(视频和音频)可以是有效的URL,也可以是 可在资源文件夹中提供

那么,是否无法播放android设备上本地存储的媒体文件?

以下是我的build.gradle文件的相关部分:

buildscript {
    // ...
    dependencies {
        classpath 'org.javafxports:jfxmobile-plugin:1.3.16'
    }
}
dependencies {
    compile 'com.gluonhq:charm:5.0.1'
    // ...
}
// ...
jfxmobile {
    downConfig {
        version = '3.8.0'
        // Do not edit the line below. Use Gluon Mobile Settings in your project context menu instead
        plugins 'display', 'lifecycle', 'statusbar', 'storage', 'video' 
    }
// ...
}
我的手机有安卓8.1

添加了用于测试目的的源代码:

int i = 0;
try {
    File privateAppStorage = Services.get(StorageService.class)
              .flatMap(StorageService::getPrivateStorage)
              .orElseThrow(() -> new FileNotFoundException("Could not access private storage."));
    String outputfilename = privateAppStorage + "/1834.mp4";

    if(i == 0) { // to skip copying set i != 0 on 2nd run
        // copy video
        File input = new File("/sdcard/DCIM/tmp/1834.mp4");
        int li = (int) input.length();
        byte[] bFile = new byte[li];
        FileInputStream fis = new FileInputStream(input);
        fis.read(bFile);
        fis.close();
        File output = new File(outputfilename);
        FileOutputStream fos = new FileOutputStream(output);
        fos.write(bFile);
        fos.flush();
        fos.close();
        li = (int) output.length();

        /* test copying routine
        File testoutput = new File("/sdcard/DCIM/tmp/1834_2.mp4");
        FileOutputStream tfos = new FileOutputStream(testoutput);
        tfos.write(bFile);
        tfos.flush();
        tfos.close();
        li = (int) testoutput.length();
        */ // end test copying routine
    }
    // play video
    Optional<VideoService> service = Services.get(VideoService.class);
    if(service.isPresent()){
        VideoService videoService = service.get();
        videoService.setControlsVisible(true);
        videoService.setFullScreen(true);
        Status status = videoService.statusProperty().get();
        ObservableList<String> sl = videoService.getPlaylist();
        if(sl.size() > 0)
            sl.set(0, outputfilename);
        else
            videoService.getPlaylist().add(outputfilename);

        videoService.show(); 
    }
} catch ( IOException e) {
    e.printStackTrace();
}
调试到
DefaultVideoService.copyFile(…)
我发现
DefaultVideoService.class.getResourceAsStream(pathIni)
语句返回null,因此DefaultVideoService内部复制失败。
为什么它返回null,我不知道,因为我没有合适的java.lang.Class源代码。

这里是我为我的环境找到的一个解决方法。 假设要播放的文件是

String filename = "/sdcard/DCIM/tmp/1834.mp4";
打电话之前

VideoService.getPlaylist.add(filename);
复制包含以下语句的文件:

File privateAppStorage = Services.get(StorageService.class)
          .flatMap(StorageService::getPrivateStorage)
          .orElseThrow(() -> new FileNotFoundException("Could not access private storage."));
File assets = new File(privateAppStorage.getAbsolutePath() + "/assets");
boolean assets_exists = assets.exists();
if(!assets.exists())
{
    assets_exists = assets.mkdir();
}
if(assets_exists && assets.canWrite())
{
    File input = new File(filename);
    int li = (int) input.length();
    byte[] bFile = new byte[li];
    FileInputStream fis = new FileInputStream(input);
    fis.read(bFile);
    fis.close();

    File copiedToAssets = new File(assets.getAbsolutePath() + "/" + filename.replaceAll("/", "_"));
    FileOutputStream fos = new FileOutputStream(copiedToAssets);
    fos.write(bFile);
    fos.flush();
    fos.close();
}

这绕过了我的问题中提到的DefaultVideoService.class.getResourceAsStream(pathIni),视频可以播放。

这里是我为我的环境找到的一个解决方法。 假设要播放的文件是

String filename = "/sdcard/DCIM/tmp/1834.mp4";
打电话之前

VideoService.getPlaylist.add(filename);
复制包含以下语句的文件:

File privateAppStorage = Services.get(StorageService.class)
          .flatMap(StorageService::getPrivateStorage)
          .orElseThrow(() -> new FileNotFoundException("Could not access private storage."));
File assets = new File(privateAppStorage.getAbsolutePath() + "/assets");
boolean assets_exists = assets.exists();
if(!assets.exists())
{
    assets_exists = assets.mkdir();
}
if(assets_exists && assets.canWrite())
{
    File input = new File(filename);
    int li = (int) input.length();
    byte[] bFile = new byte[li];
    FileInputStream fis = new FileInputStream(input);
    fis.read(bFile);
    fis.close();

    File copiedToAssets = new File(assets.getAbsolutePath() + "/" + filename.replaceAll("/", "_"));
    FileOutputStream fos = new FileOutputStream(copiedToAssets);
    fos.write(bFile);
    fos.flush();
    fos.close();
}

这绕过了我的问题中提到的
DefaultVideoService.class.getResourceAsStream(pathIni)
,可以播放视频。

您是否尝试过将视频从当前位置复制到私有存储根目录,而无需额外的文件夹,然后用它的名字将它添加到播放列表中?@JoséPereda:我将1834.mp4直接放在/data/user/0/mypackage/files下,并尝试了getPlaylist()。添加带有s=“1834.mp4”的内容以及“/data/user/0/mypackage/files/1834.mp4”的内容仍然导致了W/AndroidVideoService(…):无效的视频文件…我建议您遵循服务的java文档:直接在项目的
src/resources/video.mp4
中放置一个有效的视频,并将其添加到播放列表(
video.getPlaylist().add(“video.mp4”);
)。然后构建apk,部署和测试。如果可以,请使用“1834.mp4”(从Android设备下载到桌面计算机)再试一次。同样,如果这样做有效,这意味着该视频是一个有效的媒体文件,并且问题与将其从当前位置复制到应用程序的私有存储有关。@JoséPereda:我将
1834.mp4
从android设备复制到我的项目
src/resources
,将其部署并通过
getPlaylist()添加(“1834.mp4”)
。可以显示视频!为了验证我的复制例程,我执行了以下操作:(1)测试复制到
/sdcard/DCIM/tmp/1834\u 2.mp4
,并使用Android视频播放器启动此操作->1834\u 2.mp4可以播放(2)检查
文件输出流。刷新
可能是原因,使用I!=0跳过复制进行第二次运行(outputfile应该已经在privateAppStorage中了)。我将把我的测试源代码添加到我的帖子中。在我为
com.gloonhq.charm.down
启用调试后,我看到了一些关于
com.gloonhq.impl.charm.down.plugins.DefaultVideoService
内部复制过程的更多信息。我将把它添加到我的帖子中(参见编辑2019-06-05)您是否尝试过将视频从其当前位置复制到私有存储根目录,而不使用其他文件夹,然后仅使用其名称将其添加到播放列表中?@JoséPereda:我将1834.mp4直接放在/data/user/0/mypackage/files下,并尝试了getPlaylist()。使用s=“1834.mp4”和“/data/user/0/mypackage/files/1834.mp4”添加“两者仍然导致W/AndroidVideoService(…):无效的视频文件…我建议您遵循服务的java文档:直接在项目的
src/resources/video.mp4
中放置一个有效的视频,并将其添加到播放列表中(
video.getPlaylist().add(“video.mp4”);
)。然后构建apk,部署并测试。如果可行,请使用“1834.mp4”重试(将其从Android设备下载到桌面计算机)。同样,如果这样做有效,这意味着视频是一个有效的媒体文件,问题与将其从当前位置复制到应用程序的私有存储有关。@JoséPereda:我将
1834.mp4
从android设备复制到我的项目
src/resources
,部署并通过
getPlaylist()添加它。添加(“1834.mp4”)
。可以显示视频!为了验证我的复制例程,我执行了以下操作:(1)测试复制到
/sdcard/DCIM/tmp/1834\u 2.mp4
,并使用Android视频播放器启动此操作->1834\u 2.mp4可以播放(2)检查
文件输出流。刷新
可能是原因,使用I!=0跳过复制进行第二次运行(outputfile应该已经在privateAppStorage中了)。我将把我的测试源代码添加到我的帖子中。在我为
com.gloonhq.charm.down
启用调试后,我看到了一些关于
com.gloonhq.impl.charm.down.plugins.DefaultVideoService
内部复制过程的更多信息。我将把它添加到我的帖子中(参见编辑2019-06-05)