Мне удалось заставить это работать, и, поскольку это все еще открытый вопрос, я включу здесь полное решение.
Хотя идея изменить расширение файла, чтобы предотвратить сжатие, хороша, но я предпочитаю копировать файл srt
из ресурсов в локальный каталог приложения на устройстве, но в любом случае для полноты вот список расширений, которые выиграли не сжиматься.
".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"
Шаги решения просты:
Создайте экземпляр MediaPlayer
и подготовьте его, вызвав MediaPlayer.create()
или player.setDataSource()
, а затем player.prepare()
Если файлы субтитров еще не существуют на устройстве Android, скопируйте их из папки ресурсов на устройство.
Вызовите player.addTimedTextSource()
с первым аргументом String
, содержащим полный путь к файлу субтитров на устройстве, и MediaPlayer.MEDIA_MIMETYPE_TEXT_SUBRIP
в качестве второго аргумента.
Выберите трек TimedText
, вызвав player.selectTrack()
, и передайте the index of timedTextType
, выполнив поиск TrackInfo[]
, возвращенного из player.getTrackInfo()
(обычно я нахожу 2
).
Настройте прослушиватель с помощью player.setOnTimedTextListener()
, а затем начните воспроизведение медиафайла player.start()
.
Вот весь класс:
Чтобы запустить именно этот класс, вам потребуются два файла в папке res/raw
sub.srt
и video.mp4
(или с любым другим расширением). Затем определите TextView
с идентификатором txtDisplay
. Наконец, ваш проект/устройство/эмулятор должен поддерживать 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);
}
}
А вот файл subtitle
, который я использую в качестве примера:
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
изменяется автоматически (т. е. считывается из файла субтитров) по мере воспроизведения медиафайла.
Изменить:
Вот код для пример проекта
person
iTech
schedule
18.02.2013