Jak nagrywać strumień za pomocą libvlc.dll?

0

Witajcie,

Mam zaimplementowany komponent VLC (VideoLan) w mojej aplikacji. Strumień z sieci pobiera się bez problemu ale ... potrzebowałbym go nagrać. Finalnie z poziomu aplikacji VLC Media Player da się taki strumień zapisać. Pytanko czy macie gdzieś pod ręką jakiś przykładowy kod w delphi, który pozwoliłby mi w dowolnym momencie nagrać odpowiedni strumień na dysku?

Z googla wyciągnąłem jedynie konwersję bitmap na avi itp. Mogę to zrobić w ten sposób ale jak już używam VLC i jest tam możliwość nagrania (przynajmniej z aplikacji) to trochę bez sensu zapisywać bitmapy i robić z nich AVI ...

Będę wdzięczny za każdą pomoc.

0

http://stackoverflow.com/questions/16515099/saving-a-stream-while-playing-it-using-libvlc

nigdy tego nie używałem, ale na oko jak tworzysz to podajesz takie parametry:
wyświetlanie i zapis do example.mpg
vlc.Instance("--sout=#duplicate{dst=file{dst=example.mpg},dst=display}")
podejrzewam, że sam zapis to będzie tak:
vlc.Instance("--sout=file{dst=example.mpg}")
albo tak:
vlc.Instance("--sout=#file{dst=example.mpg}")

w delphi też pewnie coś podobnego masz jak tworzysz instancję klasy vlc

0

Mam takie coś:

  vlcInstance := libvlc_new(0, nil);
  vlcMedia := libvlc_media_new_location(vlcInstance, PAnsiChar(AnsiString(s))); 
  vlcMediaPlayer := libvlc_media_player_new_from_media(vlcMedia);
  libvlc_media_release(vlcMedia);
  libvlc_media_player_set_hwnd(vlcMediaPlayer, Pointer(pShow.Handle));
  libvlc_media_player_play(vlcMediaPlayer);

i jeszcze definicja:

  plibvlc_instance_t        = type Pointer;
  plibvlc_media_player_t    = type Pointer;
  plibvlc_media_t           = type Pointer;

var
  libvlc_media_new_path              : function(p_instance : Plibvlc_instance_t; path : PAnsiChar) : Plibvlc_media_t; cdecl;
  libvlc_media_new_location          : function(p_instance : plibvlc_instance_t; psz_mrl : PAnsiChar) : Plibvlc_media_t; cdecl;
  libvlc_media_player_new_from_media : function(p_media : Plibvlc_media_t) : Plibvlc_media_player_t; cdecl;
  libvlc_media_player_set_hwnd       : procedure(p_media_player : Plibvlc_media_player_t; drawable : Pointer); cdecl;
  libvlc_media_player_play           : procedure(p_media_player : Plibvlc_media_player_t); cdecl;
  libvlc_media_player_stop           : procedure(p_media_player : Plibvlc_media_player_t); cdecl;
  libvlc_media_player_release        : procedure(p_media_player : Plibvlc_media_player_t); cdecl;
  libvlc_media_player_is_playing     : function(p_media_player : Plibvlc_media_player_t) : Integer; cdecl;
  libvlc_media_release               : procedure(p_media : Plibvlc_media_t); cdecl;
  libvlc_new                         : function(argc : Integer; argv : PAnsiChar) : Plibvlc_instance_t; cdecl;
  libvlc_release                     : procedure(p_instance : Plibvlc_instance_t); cdecl;

  vlcLib: integer;
  vlcInstance: plibvlc_instance_t;
  vlcMedia: plibvlc_media_t;
  vlcMediaPlayer: plibvlc_media_player_t;

w tej linijce próbowałem twojej metody ... ale bez efektu

  vlcInstance := libvlc_new(0, nil);
0

w tej linijce próbowałem twojej metody ... ale bez efektu

  vlcInstance := libvlc_new(0, nil);

wklej dokladnie co tam masz

0

Próbowałem tak:

vlcInstance := libvlc_new(0, '--sout=#file{dst=example.mpg}');

lub tak

vlcInstance := libvlc_new(0, '--sout=#duplicate{dst=file{dst=example.mpg},dst=display}');

ponadto próbowałem kombinacji z pełną ścieżką do pliku np C:/example.mpg itp
próbowałem również takiego wariantu z " i " :

vlcInstance := libvlc_new(0, '"--sout=#duplicate{dst=file{dst=example.mpg},dst=display}"');

Pierwszy parametr natomiast jest numeryczny i wpisanie mu innej wartości niż 1 powoduje access violation

0

Jesli chcesz tylko sopiowac strumien, bez rekompresji to musisz zapisac do tego samego formatu, ktore posiadla zrodlo. Watpie aby strumien z kamerki byl mpg. Nigdy nie uzywalem vlclib, ale bedac na twoim miejscu najpierw bym sprawdzil to na zrodle bedacym plikiem. Otworz jakies mpg i uzyj obecnego kodu do zapisu.

1

Ja nie umiem za bardzo pomóc. No chyba, że wykorzystasz sposób na około i posłużysz się rtmpdump.exe, ale wtedy docelowy stream musi być na bazie protokołu RTMP, a Twój plik wynikowy będzie musiał być w formacie flv. Jednak ja bym spróbował skontaktować się z osobą tworzącą PasLibVlc http://prog.olsztyn.pl/paslibvlc i zapytać na e-maila czy może coś doradzić.

0

tutaj masz dobra dokumentacje komend
https://wiki.videolan.org/Documentation:Streaming_HowTo/Command_Line_Examples/

najlepiej to najpierw sprawdzic w konsoli a potem dopiero libvlc. Zakladam ze nie chce ci sie wnikac, polecam zalozyc temat na forum vlc. Tam na pewno ktos da konkretna komende do skopiowania strumienia, bez ponownej kompresji.

0

Dzięki wszystkim sprawdzę wszystkie możliwości. Jak tylko będę coś więcej wiedział z pewnością dam znać jakie było rozwiązanie.

1

Finalnie sprawdziłem każdy temat i ... pokrętnie (z wykorzystaniem pomysłu Olesia) ale zrobiłem.
Zainstalowałem sobie ten komponencik PasLibVLC (który jest tylko ładną nakładką na libVLC) do odtwarzania ekstra ale niestety schody zaczęły się przy nagrywaniu. Samo zapisanie zrzutu ekranu to pestka gdyż komponent ma już wbudowaną metodę. Niestety zaimplementowane w komponencie metody do obsługi zapisu nie do końca działały na moim strumieniu. Jednakże dorobiłem do komponentu wersję z property recording i PasLibVlcUnit.pas w funkcji PlayNormal dodałem taką linijkę kodu:

if Recording then 
  media.AddOption(':sout=#duplicate{dst=display,dst=std{access=file,mux=mp4,dst="C:\t.mp4"}}');

która działa bez zarzutu.

PS. Próbowałem się skontaktować z autorem PasLibVLC ale delikatnie mówiąc mnie olał.

PS2.
PasLibVLC jak i biblioteka libVLC umożliwia zapisywanie również np w strumieniu AVI jednak ja tego nie testowałem.

1 użytkowników online, w tym zalogowanych: 0, gości: 1