0

I am looking for a way to play 2 video in a row without any delay (or very tiny delay) when changing files.
I had 1 mp4 file and with ffmpeg I split it into 2 file and now I want to add them in playlist and play them but I don't want user feel changing video but when I test it because of loading file there is a delay.
I think about stream second file into memory before first file end. How can I do this?
I tested LibVLC and read Play a Video from MemoryStream, Using FFMpeg but still no luck.
PS : Any library in any language is good for me.

EDIT: Files are small (less than 5mb and less than 5 seconds).

EDIT: I added a demo with PasLibVLC in FreePascal that play second file after first one but there is a delay beetwen changing.How can I minimize this?(for example feeding VLC from memory and load second file into memory).

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.
Community
  • 1
  • 1
Ara Deonas
  • 83
  • 1
  • 1
  • 10
  • This question is [too broad](http://stackoverflow.com/help/on-topic). There are either too many possible answers, or good answers would be too long for this format. Please add details to narrow the answer set or to isolate an issue that can be answered in a few paragraphs. – Jørgen R Feb 10 '15 at 13:01
  • Yes maybe but I think it is clear what I want.I want to play 2 peas of a file in a row with minimum delay between changing in any library or language. – Ara Deonas Feb 10 '15 at 13:23
  • What about joining the two files into one? Seriously, stating `still no luck` means nothing. What exactly did not work and what does your code look like? – Tom Brunberg Feb 12 '15 at 19:34
  • You are right.Joining is not possible because first file is playing when second file downloading.About LibVLC I contact with PasLibVLC developer and he said that it is not possible with VLC and it is not support this situation.So because of these I need hint or example or library that good for this situation. – Ara Deonas Feb 12 '15 at 23:05
  • LibVLC has a "media list player" as well as a media player. So you could put your two videos inside a playlist. Did you look at that? Do these language bindings expose that? – caprica Feb 14 '15 at 12:36
  • Thanks,Sure I look that but problem is when it or my way change video there is a delay.I am looking for a way that change video with minimal delay. – Ara Deonas Feb 14 '15 at 14:52
  • The point is that the media list player automatically plays one video "immediately" (well as quickly as possible) after the other. In my experience it does indeed work better (more quickly) than waiting for events and invoking play yourself on a regular media player. – caprica Feb 14 '15 at 20:05
  • Thanks,and I searching for an answer for this situation but I cant make it enough fast,maybe someone else have an answer. – Ara Deonas Feb 14 '15 at 20:30
  • See here for similar question: http://stackoverflow.com/q/28703029/334402. It might be worth you guys sharing solutions if/when you find one. – Mick Feb 25 '15 at 10:49
  • Why is this question tagged `c#` and `c++`? – René Hoffmann Feb 25 '15 at 11:15
  • @René Hoffmann Because c# and c++ also good for me but I prefer Delphi or free pascal. – Ara Deonas Feb 25 '15 at 22:51

1 Answers1

0

HTML5 Media source extensions (MSE) should allow you do this, but it is tricky because you have to handle the streaming and buffering of the videos yourself. If you can find a media player with the functionality built in it would be much easier. See some more info and links to MSE in answer to similar question here:

Community
  • 1
  • 1
Mick
  • 24,231
  • 1
  • 54
  • 120