Я ищу способ воспроизвести 2 видео подряд без каких-либо задержек (или
очень маленькая задержка) при смене файлов.
У меня был 1 файл mp4 и с помощью ffmpeg я разделил его на 2 файла, и теперь я хочу
добавить их в плейлист и воспроизводить их, но я не хочу, чтобы пользователь чувствовал
изменение видео, но когда я тестирую его из-за загрузки файла, появляется
задержка.
Я думаю о потоке второго файла в память до конца первого файла.
Как я могу это сделать?
Я протестировал LibVLC и прочитал Воспроизвести видео из MemoryStream, используя FFMpeg но все равно не повезло.
PS: любая библиотека на любом языке мне подходит.
РЕДАКТИРОВАТЬ: Файлы небольшие (менее 5 МБ и менее 5 секунд).
РЕДАКТИРОВАТЬ: Я добавил демо с PasLibVLC во FreePascal, который воспроизводит второй файл после первого, но есть задержка между изменениями. Как я могу минимизировать это? (Например, подача VLC из памяти и загрузка второго файла в память).
unit MainFormUnit;
{$mode Delphi}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, Menus,LCLIntf, LCLType,
ExtCtrls, StdCtrls,PasLibVlcUnit,PasLibVlcPlayerUnit;
const
MAX_ARGS = 255;
type
{ TMainForm }
TMainForm = class(TForm)
Button1: TButton;
MenuFile: TMenuItem;
MenuFileOpen: TMenuItem;
MenuFileQuit: TMenuItem;
Panel1: TPanel;
Panel2: TPanel;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
p_li: libvlc_instance_t_ptr;
p_mi: libvlc_media_player_t_ptr;
argv: packed array[0..MAX_ARGS - 1] of ansistring;
args: packed array[0..MAX_ARGS - 1] of PAnsiChar;
argc: integer;
p_mi_ev_mgr: libvlc_event_manager_t_ptr;
procedure AddArg(Value: ansistring);
procedure PlayerInit();
procedure PlayerPlay(fileName: WideString);
procedure PlayerStop();
procedure PlayerDestroy();
procedure WmMediaPlayerEndReached(var m: TVlcMessage); message WM_MEDIA_PLAYER_END_REACHED;
public
{ Public declarations }
end;
var
MainForm: TMainForm;
procedure lib_vlc_player_event_hdlr(p_event: libvlc_event_t_ptr; Data: Pointer); cdecl;
implementation
{$R *.lfm}
procedure lib_vlc_player_event_hdlr(p_event: libvlc_event_t_ptr; Data: Pointer); cdecl;
var
Form: TMainForm;
begin
if (Data = nil) then
exit;
Form := TMainForm(Data);
if not Assigned(Form) then
exit;
case p_event^.event_type of
libvlc_MediaPlayerEndReached:
PostMessage(Form.Handle, WM_MEDIA_PLAYER_END_REACHED, WPARAM(0), LPARAM(0));
end;
end;
{ TMainForm }
procedure TMainForm.AddArg(Value: ansistring);
begin
if (argc < MAX_ARGS) then
begin
argv[argc] := Value;
args[argc] := PAnsiChar(argv[argc]);
Inc(argc);
end;
end;
procedure TMainForm.PlayerInit();
begin
libvlc_dynamic_dll_init();
if (libvlc_dynamic_dll_error <> '') then
begin
MessageDlg(libvlc_dynamic_dll_error, mtError, [mbOK], 0);
exit;
end;
argc := 0;
AddArg(libvlc_dynamic_dll_path);
AddArg('--intf=dummy');
AddArg('--ignore-config');
AddArg('--quiet');
AddArg('--no-video-title-show');
AddArg('--no-video-on-top');
p_li := libvlc_new(argc, @args);
p_mi := nil;
end;
procedure TMainForm.PlayerPlay(fileName: WideString);
var
p_md: libvlc_media_t_ptr;
a_st: ansistring;
p_st: PAnsiChar;
begin
PlayerStop();
a_st := UTF8Encode(fileName);
p_st := PAnsiChar(@a_st[1]);
p_md := libvlc_media_new_path(p_li, p_st);
if (p_md <> nil) then
begin
p_mi := libvlc_media_player_new_from_media(p_md);
if (p_mi <> nil) then
begin
libvlc_video_set_key_input(p_mi, 1);
libvlc_video_set_mouse_input(p_mi, 1);
libvlc_media_player_set_display_window(p_mi, SELF.Handle);
p_mi_ev_mgr := libvlc_media_player_event_manager(p_mi);
libvlc_event_attach(p_mi_ev_mgr, libvlc_MediaPlayerEndReached, @lib_vlc_player_event_hdlr, SELF);
end;
libvlc_media_player_play(p_mi);
libvlc_media_release(p_md);
end;
end;
procedure TMainForm.PlayerStop();
begin
if (p_mi <> nil) then
begin
libvlc_media_player_stop(p_mi);
while (libvlc_media_player_get_state(p_mi) = libvlc_Playing) do
begin
Sleep(50);
end;
libvlc_media_player_release(p_mi);
p_mi := nil;
end;
end;
procedure TMainForm.PlayerDestroy();
begin
if (p_li <> nil) then
begin
PlayerStop();
libvlc_release(p_li);
p_li := nil;
end;
end;
procedure TMainForm.WmMediaPlayerEndReached(var m: TVlcMessage);
begin
PlayerPlay('C:\ffmpeg\bin\tmp\OUTPUT1.mp4');
end;
procedure TMainForm.FormCreate(Sender: TObject);
begin
p_li := nil;
p_mi := nil;
PlayerInit();
Button1.Click;
end;
procedure TMainForm.Button1Click(Sender: TObject);
begin
PlayerPlay('C:\ffmpeg\bin\tmp\OUTPUT0.mp4');
end;
procedure TMainForm.FormDestroy(Sender: TObject);
begin
PlayerDestroy();
end;
end.
Расширения HTML5 Media source (MSE) должны позволять вам это делать, но это сложно, потому что вам приходится самостоятельно обрабатывать потоковую передачу и буферизацию видео. Если вы найдете медиаплеер со встроенной функциональностью, это будет намного проще. Смотрите дополнительную информацию и ссылки на MSE в ответ на аналогичный вопрос здесь: