В данной статье я расскажу о том, как написать плагин на языке C для медиаплеера VLC. Я написал свой плагин для упрощения просмотра сериалов и фильмов на английском языке. Идея создания этого плагина описывается в разделах Идея и Поиск решения. Технические детали реализации плагина приведены в разделах Hello World плагин и Реализация. О том, что получилось в итоге и как этим пользоваться можно прочитать в последнем разделе, Результат.
Исходный код проекта доступен на GitHub.
Идея
Идея изучать иностранный язык за просмотром любимого сериала не нова, но вот с ее воплощением в жизнь лично у меня всегда возникали проблемы. Очень сложно смотреть сериал или фильм, когда не понимаешь половину того, что там говорят. Конечно, можно включить субтитры, но если в речи встретится незнакомое слово или выражение, то от того, что оно будет продублировано текстом, яснее не станет. А смотреть сериал с русскими субтитрами мне совсем не понравилось — мозг переключается на родной язык и перестает воспринимать иностранную речь. Я где-то читал, что сначала нужно смотреть серию на русском языке, а потом уже в оригинале. Но меня такой подход тоже не устроил. Во-первых, где взять столько времени, чтобы по нескольку раз смотреть одно и то же, а во-вторых, смотреть второй раз уже не так интересно — теряется мотивация.
Несмотря на все сложности с просмотром иностранных сериалов, я довольно неплохо могу читать техническую документацию, статьи и книги на английском. Книги мне нравится читать на электронной читалке Kindle, так как там классно реализована функция работы со словарями — можно одним касанием экрана найти перевод незнакомого слова. Англоязычные статьи и сайты удобно читать, установив в браузере специальное расширение для перевода, — я пользуюсь расширением Яндекс.Перевод. Такой подход позволяет читать и понимать английские тексты, не сильно отвлекаясь на поиск незнакомых слов.
Я подумал, почему бы не применить тот же подход для просмотра сериалов — включаем серию на английском, как только встречается непонятная фраза, переключаемся на русскую аудиодорожку и отматываем немного назад. Далее продолжаем смотреть серию на английском.
Поиск решения
На самом деле, вся необходимая мне функциональность уже доступна во многих популярных медиаплеерах. Единственное, мне бы хотелось переключать аудиодорожку и отматывать видео на несколько секунд назад нажатием одной кнопки. Также было бы здорово, если бы после перевода непонятного фрагмента медиаплеер сам переключал аудиодорожку обратно на английскую. Ну и еще неплохо было бы иметь возможность повторять переведенный ранее фрагмент с английской дорожкой.
То есть, мне нужен медиаплеер, под который можно писать плагины. Желательно еще, чтобы он был кроссплатформенным, так как я пользуюсь ПК под Windows и ноутбуком под Linux. Мой выбор сразу же пал на VLC. На хабре я даже нашел статью, в которой @Idunno рассказывает, как написать расширение VLC на LUA. Кстати, это расширение он тоже написал для изучения английского) К сожалению, данное расширение не работает в последних версиях VLC (старше 2.0.5). Из-за нестабильной работы из LUA API убрали возможность добавления callback-функций, через которые в LUA-расширении можно было обрабатывать события клавиатуры. В README к своему расширению на GitHub @Idunno приводит ссылку на mailing list разработчиков VLC с обсуждением данной проблемы.
Таким образом, для реализации моей идеи расширение на LUA не подойдет, нужно писать плагин на C. И хоть я и писал что-либо на C последний раз лет 7 назад, еще в университете, решил попробовать.
Hello World плагин
Стоит отметить, что у медиаплеера VLC достаточно хорошая документация. Из нее я узнал, что при разработке медиаплеера используется модульный подход. VLC состоит из нескольких независимых модулей, реализующих определенную функциональность, и ядра (libVLCCore), которое управляет этими модулями. При этом модули бывают двух типов: внутренние (in-tree) и внешние (out-of-tree). Исходный код внутренних модулей хранится в одном репозитории с кодом ядра. Внешние модули разрабатываются и собираются независимо от медиаплеера VLC. Собственно, последние и есть то, что называют плагинами.
В документации также есть статья о том, как написать свой плагин (модуль) на языке C. В этой статье приводится исходный код простого плагина, который при запуске VLC выводит на консоль приветственное сообщение «Hello, <name>» (значение <name> берется из настроек плагина). Забегая немного вперед, скажу, что в приведенном примере нужно добавить следующую строчку после
set_category(CAT_INTERFACE)
:set_subcategory( SUBCAT_INTERFACE_CONTROL )
Отлично, осталось только собрать плагин и протестировать его работу. По сборке внешнего плагина тоже есть инструкция. Тут стоит обратить внимание на раздел Internationalization, в котором описывается, как работает локализация в VLC. Если коротко, то для внешних плагинов требуется определять макросы
N_()
, _()
:#define DOMAIN "vlc-myplugin"
#define _(str) dgettext(DOMAIN, str)
#define N_(str) (str)
Для сборки предлагается использовать старый добрый Makefile либо Autotools. Я решил пойти простым путем и выбрал Makefile. В Makefile нужно не забыть определить переменную
MODULE_STRING
— это идентификатор нашего плагина. Также я немного подправил работу с директориями — теперь они определяются через pkg-config. В итоге получились следующие файлы:/**
* @file hello.c
* @brief Hello world interface VLC module example
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#define DOMAIN "vlc-myplugin"
#define _(str) dgettext(DOMAIN, str)
#define N_(str) (str)
#include <stdlib.h>
/* VLC core API headers */
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_interface.h>
/* Forward declarations */
static int Open(vlc_object_t *);
static void Close(vlc_object_t *);
/* Module descriptor */
vlc_module_begin()
set_shortname(N_("Hello"))
set_description(N_("Hello interface"))
set_capability("interface", 0)
set_callbacks(Open, Close)
set_category(CAT_INTERFACE)
set_subcategory( SUBCAT_INTERFACE_CONTROL )
add_string("hello-who", "world", "Target", "Whom to say hello to.", false)
vlc_module_end ()
/* Internal state for an instance of the module */
struct intf_sys_t
{
char *who;
};
/**
* Starts our example interface.
*/
static int Open(vlc_object_t *obj)
{
intf_thread_t *intf = (intf_thread_t *)obj;
/* Allocate internal state */
intf_sys_t *sys = malloc(sizeof (*sys));
if (unlikely(sys == NULL))
return VLC_ENOMEM;
intf->p_sys = sys;
/* Read settings */
char *who = var_InheritString(intf, "hello-who");
if (who == NULL)
{
msg_Err(intf, "Nobody to say hello to!");
goto error;
}
sys->who = who;
msg_Info(intf, "Hello %s!", who);
return VLC_SUCCESS;
error:
free(sys);
return VLC_EGENERIC;
}
/**
* Stops the interface.
*/
static void Close(vlc_object_t *obj)
{
intf_thread_t *intf = (intf_thread_t *)obj;
intf_sys_t *sys = intf->p_sys;
msg_Info(intf, "Good bye %s!", sys->who);
/* Free internal state */
free(sys->who);
free(sys);
}
LD = ld
CC = cc
PKG_CONFIG = pkg-config
INSTALL = install
CFLAGS = -g -O2 -Wall -Wextra
LDFLAGS =
LIBS =
VLC_PLUGIN_CFLAGS := $(shell $(PKG_CONFIG) --cflags vlc-plugin)
VLC_PLUGIN_LIBS := $(shell $(PKG_CONFIG) --libs vlc-plugin)
VLC_PLUGIN_DIR := $(shell $(PKG_CONFIG) --variable=pluginsdir vlc-plugin)
plugindir = $(VLC_PLUGIN_DIR)/misc
override CC += -std=gnu99
override CPPFLAGS += -DPIC -I. -Isrc
override CFLAGS += -fPIC
override LDFLAGS += -Wl,-no-undefined,-z,defs
override CPPFLAGS += -DMODULE_STRING=\"hello\"
override CFLAGS += $(VLC_PLUGIN_CFLAGS)
override LIBS += $(VLC_PLUGIN_LIBS)
all: libhello_plugin.so
install: all
mkdir -p -- $(DESTDIR)$(plugindir)
$(INSTALL) --mode 0755 libhello_plugin.so $(DESTDIR)$(plugindir)
install-strip:
$(MAKE) install INSTALL="$(INSTALL) -s"
uninstall:
rm -f $(plugindir)/libhello_plugin.so
clean:
rm -f -- libhello_plugin.so src/*.o
mostlyclean: clean
SOURCES = hello.c
$(SOURCES:%.c=src/%.o): $(SOURCES:%.c=src/%.c)
libhello_plugin.so: $(SOURCES:%.c=src/%.o)
$(CC) $(LDFLAGS) -shared -o $@ $^ $(LIBS)
.PHONY: all install install-strip uninstall clean mostlyclean
Проще всего собрать плагин под Linux. Для этого потребуется установить, собственно, сам медиаплеер VLC, а также необходимые для сборки плагина файлы и инструменты. В Debian/Ubuntu это можно сделать с помощью следующей команды:
sudo apt-get install vlc libvlc-dev libvlccore-dev gcc make pkg-config
Собственно, все готово, собираем и устанавливаем наш плагин с помощью команды:
sudo make install
Для проверки работы плагина запускаем VLC также из консоли:
vlc
К сожалению, никакого «Hello world» мы не увидели. Все дело в том, что плагин нужно сначала включить. Для этого открываем настройки (Tools > Preferences), переключаемся на расширенный вид (выбираем All в группе Show settings) и находим в дереве на панели слева Interface > Control interfaces — ставим галочку напротив нашего плагина Hello interface.
Сохраняем настройки и перезапускаем VLC.
Сборка плагина под Windows
С Windows все немного сложнее. Для сборки плагина потребуется скачать sdk, который содержит библиотеки, заголовочные и конфигурационные файлы VLC. Раньше sdk входил в обычную сборку VLC и найти его можно было в папке установки программы. Теперь же он поставляется в виде отдельной сборки медиаплеера. Например, для VLC версии 3.0.8 эту сборку можно скачать по ссылке ftp://ftp.videolan.org/pub/videolan/vlc/3.0.8/win64/vlc-3.0.8-win64.7z (важно скачивать именно 7z-архив).
Копируем содержимое архива в какую-нибудь папку, например, в С:\Projects. Кроме sdk архив содержит и сам медиаплеер, который можно использовать для тестирования и отладки плагина.
Чтобы наш Makefile можно было использовать для сборки и установки плагина, нужно поправить файл C:\Projects\vlc-3.0.8\sdk\lib\pkgconfig\vlc-plugin.pc, указав в переменных prefix и pluginsdir корректный путь до папки с sdk и plugins соответственно:
prefix=/c/Projects/vlc-3.0.8/sdk
pluginsdir=/c/Projects/vlc-3.0.8/plugins
Для сборки под Windows нам также потребуется установить компилятор и другие утилиты. Все необходимое ПО можно получить, установив среду MSYS2. На сайте проекта есть подробная инструкция по установке. Если коротко, то сразу после установки нужно открыть консоль (C:\msys64\msys2.exe) и обновить пакеты MSYS2 с помощью команды:
pacman -Syu
Далее нужно закрыть окно терминала MSYS2, затем открыть его еще раз и выполнить команду
pacman -Su
После обновления всех пакетов нужно установить тулчейн:
pacman -S base-devel mingw-w64-x86_64-toolchain
Теперь, когда все необходимые пакеты установлены, можно приступать к сборке плагина. Я немного доработал Makefile, чтобы он мог собирать плагин как под Linux так и под Windows. Кроме того, пришлось убрать некоторые неподдерживаемые MinGW параметры сборки, в итоге Makefile стал выглядеть так:
LD = ld
CC = cc
PKG_CONFIG = pkg-config
INSTALL = install
CFLAGS = -g -O2 -Wall -Wextra
LDFLAGS =
LIBS =
VLC_PLUGIN_CFLAGS := $(shell $(PKG_CONFIG) --cflags vlc-plugin)
VLC_PLUGIN_LIBS := $(shell $(PKG_CONFIG) --libs vlc-plugin)
VLC_PLUGIN_DIR := $(shell $(PKG_CONFIG) --variable=pluginsdir vlc-plugin)
plugindir = $(VLC_PLUGIN_DIR)/misc
override CC += -std=gnu99
override CPPFLAGS += -DPIC -I. -Isrc
override CFLAGS += -fPIC
override LDFLAGS += -Wl,-no-undefined
override CPPFLAGS += -DMODULE_STRING=\"hello\"
override CFLAGS += $(VLC_PLUGIN_CFLAGS)
override LIBS += $(VLC_PLUGIN_LIBS)
SUFFIX := so
ifeq ($(OS),Windows_NT)
SUFFIX := dll
endif
all: libhello_plugin.$(SUFFIX)
install: all
mkdir -p -- $(DESTDIR)$(plugindir)
$(INSTALL) --mode 0755 libhello_plugin.$(SUFFIX) $(DESTDIR)$(plugindir)
install-strip:
$(MAKE) install INSTALL="$(INSTALL) -s"
uninstall:
rm -f $(plugindir)/libhello_plugin.$(SUFFIX)
clean:
rm -f -- libhello_plugin.$(SUFFIX) src/*.o
mostlyclean: clean
SOURCES = hello.c
$(SOURCES:%.c=src/%.o): $(SOURCES:%.c=src/%.c)
libhello_plugin.$(SUFFIX): $(SOURCES:%.c=src/%.o)
$(CC) $(LDFLAGS) -shared -o $@ $^ $(LIBS)
.PHONY: all install install-strip uninstall clean mostlyclean
Так как MSYS2 ничего не знает о нашем sdk для VLC, то перед сборкой нужно добавить в переменную окружения PKG_CONFIG_PATH путь до папки pkgconfig из этого sdk. Открываем консоль MinGW (C:\msys64\mingw64.exec) и выполняем команды:
export PKG_CONFIG_PATH=/c/projects/vlc-3.0.8/sdk/lib/pkgconfig:$PKG_CONFIG_PATH
make install
Для проверки работы плагина запускаем VLC также из консоли:
/c/projects/vlc-3.0.8/vlc
Как и в случае с Linux, идем в настройки и включаем наш плагин. Сохраняем настройки и перезапускаем VLC.
Реализация плагина
Для реализации моего плагина мне необходимо было понять, как управлять медиаплеером (менять аудиодорожку, перематывать назад) и как обрабатывать события нажатия клавиш клавиатуры. Чтобы разобраться во всем этом, я обратился к документации. Также в Интернете я нашел пару интересных статей, проливающих свет на архитектуру медиаплеера: The architecture of VLC media framework и VLC media player API Documentation.
VLC состоит из большого количества независимых модулей (400+). Каждый модуль должен предоставлять информацию о типе реализуемой им функциональности, а также функции инициализации/финализации. Данная информация описывается в блоке vlc_module_begin() — vlc_module_end() с помощью макросов set_capability() и set_callbacks(). Функции инициализации/финализации модуля (обычно они называются Open и Close) имеют следующую сигнатуру:
static int Open(vlc_object_t *)
static void Close(vlc_object_t *)
vlc_object_t — это базовый тип для представления данных в VLC, от которого наследуются все остальные (см. статью Object_Management). Указатель на vlc_object_t нужно приводить к конкретному типу данных в соответствии с той функциональностью, которую реализует модуль. Для управления медиаплеером я указал в макросе set_capability() значение interface. Соответственно, в функциях Open и Close мне нужно привести vlc_object_t к intf_thread_t.
Взаимодействие между модулями построено на основе шаблона проектирования observer. VLC предоставляет механизм «object variables» (см. статью Variables), с помощью которого в экземпляры типа vlc_object_t (и его производные) можно добавлять переменные. Через эти переменные модули могут обмениваться данными. Также на переменную можно навесить callback-функцию, которая будет вызываться при изменении значения этой переменной.
В качестве примера можно рассмотреть модуль Hotkeys (modules/control/hotkeys.c), который отвечает за обработку событий нажатия горячих клавиш. В функции Open на переменную key-action навешивается callback-функция ActionEvent:
var_AddCallback( p_intf->obj.libvlc, "key-action", ActionEvent, p_intf );
В функцию var_AddCallback передается указатель на vlc_object_t, имя переменной, callback-функция и указатель на void для передачи произвольных данных, которые потом пробрасываются в указанную callback-функцию. Сигнатура callback-функции приведена ниже.
static int ActionEvent(vlc_object_t *, char const *, vlc_value_t, vlc_value_t, void *)
В качестве параметров в callback-функцию передается указатель на vlc_object_t, имя переменной, старое и новое значение этой переменной (в данном случае, идентификатор соответствующего нажатой комбинации горячих клавиш действия), а также заданный при добавлении callback-функции указатель на какие-либо дополнительные данные.
Непосредственно обработка событий горячих клавиш выполняется в функции PutAction, которая вызывается внутри callback-функции ActionEvent. Функция PutAction принимает на вход идентификатор события нажатия комбинации горячих клавиш (i_action) и с помощью оператора switch выполняет соответствующие действия.
Например, событию перемотки назад соответствует значение
ACTIONID_JUMP_BACKWARD_SHORT
. Для выполнения соответствующего действия из настроек VLC берется интервал перемотки (из переменной short-jump-size):mtime_t it = var_InheritInteger( p_input, varname );
Чтобы перемотать проигрываемый файл, достаточно присвоить переменной time-offset значение, соответствующее времени (в микросекундах), на которое нужно сместить воспроизведение:
var_SetInteger( p_input, "time-offset", it * sign * CLOCK_FREQ );
Для перемотки вперед нужно указать положительное значение, для перемотки назад — отрицательное. Константа CLOCK_FREQ используется для конвертации секунд в микросекунды.
Аналогичным образом происходит смена аудиодорожки (событие
ACTIONID_AUDIO_TRACK
). Только отвечающая за аудиодорожку переменная audio-es может принимать ограниченный набор значений (в соответствии с имеющимися в проигрываемом файле аудиодорожками). Получить список возможных значений переменной можно с помощью функции var_Change():vlc_value_t list, list2;
var_Change( p_input, "audio-es", VLC_VAR_GETCHOICES, &list, &list2 );
Помимо списка значений эта функция также позволяет получить список описаний этих значений (в данном случае название аудиодорожек). Теперь мы можем поменять аудиодорожку с помощью функции var_Set():
var_Set( p_input, "audio-es", list.p_list->p_values[i] );
Как управлять медиаплеером разобрались, осталось научиться обрабатывать события клавиатуры. К сожалению, добавить новую горячую клавишу у меня не получилось. Все горячие клавиши жестко зашиты в коде ядра VLC (src/misc/actions.c). Поэтому я добавил обработчик более низкоуровневых событий нажатия клавиш клавиатуры, повесив свою callback-функцию на изменение переменной key-pressed:
var_AddCallback( p_intf->obj.libvlc, "key-pressed", KeyboardEvent, p_intf );
В переменной key-pressed хранится код символа (в Unicode), соответствующего последней нажатой клавише. Например, при нажатии клавиши с цифрой «1» переменной key-pressed будет присвоено значение 49 (0x00000031 в 16ой системе счисления). Посмотреть коды других символов можно на сайте unicode-table.com. Кроме того, в значении переменной key-pressed учитывается нажатие клавиш-модификаторов, для них отведен четвертый значащий байт. Так, например, при нажатии комбинации клавиш «Ctrl + 1» переменной key-pressed будет присвоено значение 0x04000031 (00000100 00000000 00000000 001100012). Для наглядности в таблице ниже приведены значения различных комбинаций клавиш:
Комбинация клавиш | Значение |
---|---|
Ctrl + 1 | 00000100 00000000 00000000 001100012 |
Alt + 1 | 00000001 00000000 00000000 001100012 |
Ctrl + Alt + 1 | 00000101 00000000 00000000 001100012 |
Shift + 1 | 00000010 00000000 00000000 001000012 |
Результат
Я назвал свой плагин TIP — акроним от фразы «translate it, please», также tip можно перевести как «подсказка». Исходный код плагина опубликован на GitHub, там же можно скачать готовые сборки плагина под Windows и Linux.
Для установки плагина нужно скопировать файл libtip_plugin.dll (libtip_plugin.so для Linux) в папку <path-to-vlc>/plugins. В Windows VLC обычно устанавливается в папку C:\Program Files\VideoLAN\VLC. В Linux найти папку установки можно с помощью команды:
whereis vlc
В Ubuntu, например, VLC ставится в /usr/lib/x86_64-linux-gnu/vlc.
Далее потребуется перезапустить VLC, затем в главном меню открыть Tools > Preferences, переключиться на расширенный вид (выбрать All в группе Show settings), на панели слева перейти в раздел Interface > Control и поставить галочку напротив пункта TIP (translate it, please). После чего снова потребуется перезапуск VLC.
В настройках плагина можно указать номера основной и вспомогательной (для перевода) аудиодорожек, а также время (в секундах), на которое плагин будет отматывать назад для повтора со вспомогательной аудиодорожкой.
Для управления плагином я добавил следующие горячие клавиши:
- «/» для перевода
- «Shift + /» для повтора переведенного ранее фрагмента видео с основной аудиодорожкой
Во время выполнения команд перевода и повтора плагин отображает в верхнем левом углу сообщения «TIP: translate» и «TIP: repeat» соответственно.
По своему опыту использования плагина могу сказать, что, в целом, я доволен результатом. Главное, правильно подобрать контент, если будет понятна хотя бы половина используемой там иностранной речи, плагин поможет перевести остальное. В противном случае плагин, наверное, будет бесполезен.
Комментарии (27)
LibrarianOok
15.11.2019 18:26Жаль, что никаким плагином не исправить корявость собственно переводов.
Lazytech
16.11.2019 08:11Справедливости ради скажу, что корявость при переводе фильмов и сериалов иногда вынужденная, потому что далеко не всегда можно перевести одновременно и кратко, и понятно для целевой аудитории, и в строгом соответствии с оригиналом.
artem_ibragimov
15.11.2019 21:22+1Столкнулся с такой же проблемой: с субтитрами читаешь только текст, без них не понимаешь половину.
В моей реализации проигрывается видео,
при перемотке назад появляются англ.субтитры,
при повторной перемотке появляются сдвоенные субтитры.
После перемотанного фрагмента, субтитры исчезают.Andrey_Epifantsev
16.11.2019 03:21+1А где можно посмотреть вашу реализацию?
artem_ibragimov
16.11.2019 09:55+1interprise
16.11.2019 11:40Выглядит не плохо, ваш проект открытый или коммерческий?
artem_ibragimov
16.11.2019 13:06неоткрытый и некоммерческий хобби-проект — попробовать react.
interprise
16.11.2019 13:16Может сделать открытым? Я бы хотел воспользоваться, но у вас очень мало видео.
Alcpp
16.11.2019 05:55Только на втором экране я узнал в чем идея.
Я подумал, почему бы не применить тот же подход для просмотра сериалов — включаем серию на английском, как только встречается непонятная фраза, переключаемся на русскую аудиодорожку и отматываем немного назад. Далее продолжаем смотреть серию на английском.
Желаельно такую инфу віносить в шапку.
VIRT_nsk
16.11.2019 08:56У меня давно уже есть идея попробовать запустить обе озвучки одновременно, только в разных каналах, например, в левое ухо — русскую, а в правое — оригинал. Естественно, нужно чтобы они были точно синхронизированы. Думаю, восприятие очень быстро приспособится к такому потоку информации и можно будет мысленно переключаться на любую из них когда угодно. Тем более, если услышал что-то незнакомое — можно просто вспомнить что было секунду назад в русском канале. Только никак не получается найти достаточно времени на реализацию, да опыта на С у меня нет. Может кто-нибудь захочет реализовать что-то подобное?
ru1z
16.11.2019 12:13Не приспособится, во-первых, будет каша из звуков (попробуйте учить в толпе), а во вторых переводы неидеальны. Третий контрагумент, то что идея — очень простая, легко до нее додуматься, но при этом ни одной техники обучения языками на этой основе не видно. Кроме того непонятно, чем это лучше субтитров, которые формально как бы используют визуальный канал с большей пропускной способностью. Ну и в заключение — смотреть фильмы для обучения — в принципе малоэффективно, это просто аудирование с ситуативной поддержкой. Обычно фильмы — только подкрепляющее, малоэффективное средство для изучения именно языков, если только это не специальные курсы для обучения.
Можете для интереса вручную с двух устройств запускать разные дорожки и проверить. Или в любом аудиоредакторе, например, Audacity, заменить одну из аудиодорожек на дорожку из дубляжа. Ну или если хочется более готового решения, то это вероятно можно накодить грубо с помощью ffmpeg trac.ffmpeg.org/wiki/AudioChannelManipulationVIRT_nsk
16.11.2019 14:04В том то и дело, что нужно синхронизировать обе дорожки(фон должен быть общим), но озвучку не совмещать в один канал, а использовать разные. Каша будет только если обез озвучки смешаны вместе, как раз как в толпе, а тут — четкая речь в каждом(ухе) раздельно. Я легко могу сосредоточиться на одном направлении и внимательно слушать именно оттуда, при этом могу запросто вспомнить что было слышно за последние несколько секунд в другом.
И это не просто для обучения, изначально уже должны быть некоторые навыки и знания. Это для улучшения восприятия зарубежной речи от носителей языка, часто в профессиональной озвучке. Она лучше воспринимается изначально, хотя и немного дальше от бытового разговора. Это практика, чем больше прослушаешь известные формулировки, тем проще их потом находить в реальном разговоре, это будет происходить уже на автомате, не задумываясь.
Субтитры хорошо, но они слишком отвлекают от видео.gearbox
16.11.2019 14:46>Субтитры хорошо, но они слишком отвлекают от видео.
Определитесь зачем вы смотрите видео?
Получить удовольствие? Есть три опции — смотреть в переводе, выучить язык и смотреть в оригинале, выучить сами субтитры до просмотра и смотреть зная содержимое.
Выучить/подтянуть язык? Страдайте.
ru1z
16.11.2019 15:28\\ фон должен быть общим
Я же написал как это сделать. Берете мультиязыковой фильм (например часто такие в mkv), вытаскиваете дорожки, потом совмещаете в одну стерео-дорожку. Учтите, что перевод может и будет отличаться немного, как и длина фразы. Вот специально для вас, в аудасити, сделал пофразно аудиофайл https://www.mediafire.com/file/xkwingkxu6qnet1/TotoroEN2mandarin.mp3/file из того что подвернулось под руку (одна дорожка английский, вторая китайский). Заняло всего три минуты.
\\ Это для улучшения восприятия зарубежной речи от носителей языка, часто в профессиональной озвучке.
Сдается мне что это все рассуждения, без тщательного исследования вопроса. Даже если вам это вдруг помогает, то еще нужно доказать, что это не чисто ваш энтузиазм и то, что другим поможет такой явно затратный вариант.
grey_rat
17.11.2019 01:02А возможно ли под новые браузеры написать плагин VLC не NPAPI? Раньше можно было поставить плагин VLC или WMP и смотреть видео ютуба в плеере прямо на веб-странице. Сейчас ничего похожего нет.
rasswet
18.11.2019 10:27мне нравится идея, когда смотришь без сабов, если не понял, нажал кнопку, появились сабы на двух языках фраз 1-5 назад от текущей. Прочитал, и дальше снова без сабов смотришь. на пазлинглише так сделано, но у них не так уж много сериалов доступных, которые мне интересно.
vanyas
Жаль это к стриминговым сервисам типа нетфликса не прикрутишь
Tarson
Можно Java прикрутить к стримингу через фреймворк VLCJ
Я делал (см. мои публикации), просто стриминг по udp, но там можно что угодно и файлы и RTP протоколы. Плюс кнопки и окна с плеером интегрируются на раз. Похоже, вообще весь command line VLC можно через этот фреймворк прикрутить.
ahnyava
ororo.tv
Amistad
Оффтопик. Посоветуйте, как решить обратную задачу стриминга.
Предположим, есть устройство/компьютер, которое может посылать в интернет до 100 КБ неких данных/секунду.
Как сохранять этот поток в файлы (FTP сервер или БД) понятно.
А есть ли какое-нибудь «решение из коробки», чтобы сервер просто получал данные, держал их в RAM-памяти и отдавал всем по запросу?
Calc
vlc+vls
посмотреть в сторону vlm
посмотреть в сторону multicast+igmp
vlc всё это умеет, информации вроде хватает.
Если чего то не найдете, то можно покопаться в моих древних исходниках:
github.com/Calc86/dvr/tree/master/bin/system2/classes/vlc
Можно посмотреть в сторону gstreamer или icecast (вроде умеет работать с видео)