【问题标题】:Unable to Set Subtitles with VLC for Android无法使用 VLC for Android 设置字幕
【发布时间】:2018-02-07 10:43:51
【问题描述】:

我在启动 VLC for Android 的 VideoPlayerActivity 时无法设置字幕位置。我的目标是 API 27 并使用 FileProvider 来允许访问文件。

根据文档here,如果你设置了“subtitles_location”额外,那么你可以提供字幕文件的路径。不幸的是,我似乎无法让它工作。

我看到“字幕”菜单项仍然灰显,下载字幕似乎并没有改变这种状态。点击时,“选择字幕文件”VLC 指出目录中没有字幕文件,并且 URI 以“content://”为前缀,正如预期的那样。

视频文件和字幕文件共享同一个父目录,并使用 FileProvider 提供。

当 API >= 24 时如何设置字幕文件?

更新:

  • 似乎在点击字幕选择菜单项时,它使用 视频文件的父目录。 This is seen here.
  • 想通了,请参阅下面的解决方案。

下面是一些关于我如何通过意图启动 VideoPlayerActivity 的代码 sn-ps。

播放视频方法:

/**
 * Play a video using VLC media player. This method will play media by using
 * the VLC VideoPlayerActivity.
 *
 * @param activity         The current activity.
 * @param authority        The FileProvider authority.
 * @param vlcPackageName   The VLC package name.
 * @param vlcActivityName  The VLC activity name.
 * @param videoFile        The video file to play.
 * @param subtitlesFile    The subtitles file to play.
 * @param playbackPosition The playback position.
 * @param requestCode      The activity for result request code.
 */
public static void playVideo(
        AppCompatActivity activity,
        String authority,
        String vlcPackageName,
        String vlcActivityName,
        String vlcTitleExtra,
        String vlcPositionExtra,
        String vlcFromStartExtra,
        String vlcSubtitlesExtra,
        File videoFile,
        File subtitlesFile,
        long playbackPosition,
        int requestCode
) {
    Intent intent = new Intent(Intent.ACTION_VIEW);

    intent.setPackage(vlcPackageName);

    // Set component to VLC video player activity.
    intent.setComponent(new ComponentName(
            vlcPackageName,
            vlcActivityName
    ));

    // Set intent permission flags.
    intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
    intent.addFlags(Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
    intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

    // Set title and playback position.
    intent.putExtra(vlcTitleExtra, videoFile.getName());
    intent.putExtra(vlcPositionExtra, playbackPosition);
    intent.putExtra(vlcFromStartExtra, false);

    // Set video file location
    intent.setDataAndTypeAndNormalize(
            FileProvider.getUriForFile(
                    activity,
                    authority,
                    videoFile
            ),
            "video/*"
    );

    // Subtitles file provided, set location on intent.
    if (subtitlesFile != null) {
        intent.putExtra(
                vlcSubtitlesExtra,
                FileProvider.getUriForFile(
                        activity,
                        authority,
                        subtitlesFile
                )
        );
    }

    activity.startActivityForResult(intent, requestCode);
}

清单中的提供者定义

   <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.masterwok.bitcast.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true" >
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/paths" />
    </provider>

@xml/paths 定义:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path
        name="Download"
        path="Download/"/>
</paths>

【问题讨论】:

    标签: android vlc vlc-android


    【解决方案1】:

    我能够通过使用未记录的“item_location”额外定义来解决这个问题:here

    这解决了目标 API >= 24 时的权限问题。发生的情况是 VideoPlayerActivity 试图读取使用 FileProvider 提供的 URI 的父目录。如果我不得不猜测,我会说 Android 不允许这样做。

    通过使用额外的“item_location”传递URI,我们可以绕过这个限制。

    我现在用来播放视频文件的方法如下:

    /**
     * Play a video using VLC media player. This method will play media by using
     * the VLC VideoPlayerActivity.
     *
     * @param activity         The current activity.
     * @param vlcPackageName   The VLC package name.
     * @param vlcActivityName  The VLC activity name.
     * @param videoFile        The video file to play.
     * @param playbackPosition The playback position.
     * @param requestCode      The activity for result request code.
     */
    public static void playVideo(
            AppCompatActivity activity,
            String vlcPackageName,
            String vlcActivityName,
            String vlcItemLocationExtra,
            String vlcTitleExtra,
            String vlcPositionExtra,
            String vlcFromStartExtra,
            File videoFile,
            long playbackPosition,
            int requestCode
    ) {
        Intent intent = new Intent(Intent.ACTION_VIEW);
    
        intent.setPackage(vlcPackageName);
    
        // Set component to VLC video player activity.
        intent.setComponent(new ComponentName(
                vlcPackageName,
                vlcActivityName
        ));
    
        // Set intent permission flags.
        intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
        intent.addFlags(Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
        intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    
        // Set title and playback position.
        intent.putExtra(vlcTitleExtra, videoFile.getName());
        intent.putExtra(vlcPositionExtra, playbackPosition);
        intent.putExtra(vlcFromStartExtra, false);
    
        // Set video file location (subtitles are found by VLC by using parent directory).
        intent.putExtra(vlcItemLocationExtra, Uri.fromFile(videoFile));
    
        activity.startActivityForResult(intent, requestCode);
    }
    

    【讨论】:

    • 如果要传递带有意图的字幕怎么办?在您提供的解决方案中,用户仍然需要在 VLC 中选择字幕文件
    • 我无法完成这项工作。 setComponent 中的 VLC 视频播放器活动是什么意思?
    • 嘿@mahdi,我已经有一段时间没有看过这段代码了。使用setComponent 用于直接启动媒体播放器活动。这在文档wiki.videolan.org/Android_Player_Intents#Extras_.28optional.29 中有概述
    • 就您的第一个问题而言,我看不出有任何代表用户选择字幕的意图。可能的意图值在MediaPlayerActivity 评论下:code.videolan.org/videolan/vlc-android/-/blob/master/…
    • item_location 可能只适用于我的用例,因为我的字幕与视频文件位于同一目录中。我不确定,因为我已经离开这个代码库很长一段时间了。祝你好运!
    猜你喜欢
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 2016-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多