且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

寻找addTimedTextSource的工作示例用于从.srt文件,在安卓4.1添加字幕到视频

更新时间:2021-09-20 02:05:22

我能得到这个工作,因为它仍然是一个悬而未决的问题,我会在这里包含了完整的解决方案。

I was able to get this to work and since it is still an open question I will include the complete solution here.

虽然改变文件扩展名,以prevent的COM pression是不错的主意,但我preFER到 SRT 文件的复制的资源的设备,但反正为了这里的完整性上的应用程序的本地目录的扩展,也不会玉米pressed

Although the idea of changing the file extension to prevent the compression is nice, but I prefer to copy the srt file from the resources to the app local directory on the device, but anyways for the sake of completeness here is a list of extensions that won't be compressed.

。JPG,.JPEG,巴纽,名为.gif,.WAV,.mp2,MP3,.OGG,.AAC   .MPG,文件.mpeg,。中旬,.midi,.smf,.jet,.rtttl,.imy,.xmf,的MP4, .M4A,的.m4v,名为.3gp,.3gpp,.3g2,.3gpp2,AMR,.awb,WMA,.WMV

".jpg", ".jpeg", ".png", ".gif", ".wav", ".mp2", ".mp3", ".ogg", ".aac", ".mpg", ".mpeg", ".mid", ".midi", ".smf", ".jet", ".rtttl", ".imy", ".xmf", ".mp4", ".m4a", ".m4v", ".3gp", ".3gpp", ".3g2", ".3gpp2",".amr", ".awb", ".wma", ".wmv"

解决方法步骤很简单:

  1. 通过创建一个的MediaPlayer 实例和prepare,要么调用 MediaPlayer.create() player.setDataSource()然后播放器。prepare()

  1. Create a MediaPlayer instance and prepare it by either calling MediaPlayer.create() or player.setDataSource() then player.prepare()

如果字幕文件尚未在Android设备上存在,从资源文件夹复制到设备

If the subtitle files does not already exists on the android device, copy it from the resource folder to the device

呼叫 player.addTimedTextSource()的第一个参数字符串包含的完整路径中的的字幕文件的设备上和 MediaPlayer.MEDIA_MIMETYPE_TEXT_SUBRIP 作为第二个参数

Call player.addTimedTextSource() with the first argument a String that contains the full path of the subtitle file on the device and MediaPlayer.MEDIA_MIMETYPE_TEXT_SUBRIP as the second argument

通过调用选择时间文字跟踪 player.selectTrack()并通过 timedTextType 的通过搜索从 TrackInfo [] 返回> player.getTrackInfo()指数>(我觉得它通常 2

Select the TimedText track by calling player.selectTrack() and pass the index of timedTextType by searching the TrackInfo[] returned from player.getTrackInfo() (I find it usually 2)

设置一个侦听器 player.setOnTimedTextListener(),然后开始播放媒体文件 player.start()

Set up a listener with player.setOnTimedTextListener() and then start playing the media file player.start()

下面是完整的类:

要运行这个确切类,你需要在你的水库两个文件/原文件夹 sub.srt video.mp4 (或任何扩展)。然后定义一个的TextView id为 txtDisplay 。最后,你的项目/设备/仿真器必须支持 API 16

To run this exact class you will need two files under your res/raw folder sub.srt and video.mp4 (or whatever extensions). Then define a TextView with the id txtDisplay. Finally your project/device/emulator must support API 16

public class MainActivity extends Activity implements OnTimedTextListener {
    private static final String TAG = "TimedTextTest";
    private TextView txtDisplay;
    private static Handler handler = new Handler();

    @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    txtDisplay = (TextView) findViewById(R.id.txtDisplay);
    MediaPlayer player = MediaPlayer.create(this, R.raw.video);
    try {
        player.addTimedTextSource(getSubtitleFile(R.raw.sub),
                MediaPlayer.MEDIA_MIMETYPE_TEXT_SUBRIP);
        int textTrackIndex = findTrackIndexFor(
                TrackInfo.MEDIA_TRACK_TYPE_TIMEDTEXT, player.getTrackInfo());
        if (textTrackIndex >= 0) {
            player.selectTrack(textTrackIndex);
        } else {
            Log.w(TAG, "Cannot find text track!");
        }
        player.setOnTimedTextListener(this);
        player.start();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

private int findTrackIndexFor(int mediaTrackType, TrackInfo[] trackInfo) {
    int index = -1;
    for (int i = 0; i < trackInfo.length; i++) {
        if (trackInfo[i].getTrackType() == mediaTrackType) {
            return i;
        }
    }
    return index;
}

private String getSubtitleFile(int resId) {
    String fileName = getResources().getResourceEntryName(resId);
    File subtitleFile = getFileStreamPath(fileName);
    if (subtitleFile.exists()) {
        Log.d(TAG, "Subtitle already exists");
        return subtitleFile.getAbsolutePath();
    }
    Log.d(TAG, "Subtitle does not exists, copy it from res/raw");

    // Copy the file from the res/raw folder to your app folder on the
    // device
    InputStream inputStream = null;
    OutputStream outputStream = null;
    try {
        inputStream = getResources().openRawResource(resId);
        outputStream = new FileOutputStream(subtitleFile, false);
        copyFile(inputStream, outputStream);
        return subtitleFile.getAbsolutePath();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        closeStreams(inputStream, outputStream);
    }
    return "";
}

private void copyFile(InputStream inputStream, OutputStream outputStream)
        throws IOException {
    final int BUFFER_SIZE = 1024;
    byte[] buffer = new byte[BUFFER_SIZE];
    int length = -1;
    while ((length = inputStream.read(buffer)) != -1) {
        outputStream.write(buffer, 0, length);
    }
}

// A handy method I use to close all the streams
private void closeStreams(Closeable... closeables) {
    if (closeables != null) {
        for (Closeable stream : closeables) {
            if (stream != null) {
                try {
                    stream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

@Override
public void onTimedText(final MediaPlayer mp, final TimedText text) {
    if (text != null) {
        handler.post(new Runnable() {
            @Override
            public void run() {
                int seconds = mp.getCurrentPosition() / 1000;

                txtDisplay.setText("[" + secondsToDuration(seconds) + "] "
                        + text.getText());
            }
        });
    }
}

// To display the seconds in the duration format 00:00:00
public String secondsToDuration(int seconds) {
    return String.format("%02d:%02d:%02d", seconds / 3600,
            (seconds % 3600) / 60, (seconds % 60), Locale.US);
}
}

这里是字幕文件我使用为例:

And here is the subtitle file I am using as example:

1
00:00:00,220 --> 00:00:01,215
First Text Example

2
00:00:03,148 --> 00:00:05,053
Second Text Example

3
00:00:08,004 --> 00:00:09,884
Third Text Example

4
00:00:11,300 --> 00:00:12,900
Fourth Text Example

5
00:00:15,500 --> 00:00:16,700
Fifth Text Example

6
00:00:18,434 --> 00:00:20,434
Sixth Text Example

7
00:00:22,600 --> 00:00:23,700
Last Text Example

下面是测试程序显示出一些截图,该的TextView 自动改变(即从字幕文件中读取)的媒体文件的进展

Here are few screenshots from the test app showing that the TextView is changing automatically (i.e. reading from the subtitle file) as the media file progresses

寻找addTimedTextSource的工作示例用于从.srt文件,在安卓4.1添加字幕到视频

编辑:

下面是$ C $下实例项目