mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-21 09:58:13 +00:00
ADD: Play sounds using GStreamer under Linux/FreeBSD
(cherry picked from commit dabd5fbdc2)
This commit is contained in:
parent
e6c959cbc5
commit
6eb3e31fec
3 changed files with 165 additions and 8 deletions
141
src/platform/unix/gst.pas
Normal file
141
src/platform/unix/gst.pas
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
unit gst;
|
||||
|
||||
{$mode delphi}
|
||||
{$packenum 4}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
SysUtils, CTypes, uGlib2;
|
||||
|
||||
const
|
||||
GST_CLOCK_TIME_NONE = UInt64(-1);
|
||||
|
||||
const
|
||||
GST_MESSAGE_EOS = (1 << 0);
|
||||
GST_MESSAGE_ERROR = (1 << 1);
|
||||
|
||||
type
|
||||
GstState = (
|
||||
GST_STATE_VOID_PENDING = 0,
|
||||
GST_STATE_NULL = 1,
|
||||
GST_STATE_READY = 2,
|
||||
GST_STATE_PAUSED = 3,
|
||||
GST_STATE_PLAYING = 4
|
||||
);
|
||||
|
||||
GstStateChangeReturn = (
|
||||
GST_STATE_CHANGE_FAILURE = 0,
|
||||
GST_STATE_CHANGE_SUCCESS = 1,
|
||||
GST_STATE_CHANGE_ASYNC = 2,
|
||||
GST_STATE_CHANGE_NO_PREROLL = 3
|
||||
);
|
||||
|
||||
type
|
||||
GstClockTime = guint64;
|
||||
PGstBus = type Pointer;
|
||||
PGstElement = type Pointer;
|
||||
PGstMessage = type Pointer;
|
||||
PGstMiniObject = type Pointer;
|
||||
GstMessageType = type Integer;
|
||||
|
||||
var
|
||||
gst_object_unref: procedure(object_: gpointer); cdecl;
|
||||
gst_element_get_bus: function(element: PGstElement): PGstBus; cdecl;
|
||||
gst_mini_object_unref: procedure(mini_object: PGstMiniObject); cdecl;
|
||||
gst_init_check: function(argc: pcint; argv: PPChar; error: PPGError): gboolean; cdecl;
|
||||
gst_element_set_state: function(element: PGstElement; state: GstState): GstStateChangeReturn; cdecl;
|
||||
gst_element_factory_make: function(const factoryname: Pgchar; const name: Pgchar): PGstElement; cdecl;
|
||||
gst_bus_timed_pop_filtered: function(bus: PGstBus; timeout: GstClockTime; types: GstMessageType): PGstMessage; cdecl;
|
||||
|
||||
function GST_Initialize: Boolean;
|
||||
function GST_Play(const FileName: String): Boolean;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
URIParser, LazLogger, DCOSUtils, uGObject2;
|
||||
|
||||
function WaitMsg(Parameter: Pointer): PtrInt;
|
||||
var
|
||||
bus: PGstBus;
|
||||
msg: PGstMessage;
|
||||
playbin: PGstElement absolute Parameter;
|
||||
begin
|
||||
Result:= 0;
|
||||
bus:= gst_element_get_bus(playbin);
|
||||
|
||||
msg:= gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_EOS or GST_MESSAGE_ERROR);
|
||||
if Assigned(msg) then
|
||||
begin
|
||||
gst_mini_object_unref(msg);
|
||||
end;
|
||||
|
||||
gst_object_unref(bus);
|
||||
gst_element_set_state(playbin, GST_STATE_NULL);
|
||||
gst_object_unref(playbin);
|
||||
end;
|
||||
|
||||
function GST_Play(const FileName: String): Boolean;
|
||||
var
|
||||
playbin: PGstElement;
|
||||
res: GstStateChangeReturn;
|
||||
begin
|
||||
playbin:= gst_element_factory_make ('playbin', 'playbin');
|
||||
|
||||
Result:= Assigned(playbin);
|
||||
|
||||
if Result then
|
||||
begin
|
||||
g_object_set(playbin, 'uri', [Pgchar(FilenameToURI(FileName)), nil]);
|
||||
|
||||
BeginThread(@WaitMsg, playbin);
|
||||
|
||||
res:= gst_element_set_state(playbin, GST_STATE_PLAYING);
|
||||
|
||||
Result:= (res <> GST_STATE_CHANGE_FAILURE);
|
||||
end;
|
||||
end;
|
||||
|
||||
const
|
||||
gstlib = 'libgstreamer-1.0.so.0';
|
||||
|
||||
var
|
||||
libgst: TLibHandle;
|
||||
|
||||
function GST_Initialize: Boolean;
|
||||
var
|
||||
AMsg: String;
|
||||
AError: PGError = nil;
|
||||
begin
|
||||
libgst:= SafeLoadLibrary(gstlib);
|
||||
Result:= (libgst <> NilHandle);
|
||||
if Result then
|
||||
try
|
||||
gst_init_check:= SafeGetProcAddress(libgst, 'gst_init_check');
|
||||
gst_object_unref:= SafeGetProcAddress(libgst, 'gst_object_unref');
|
||||
gst_element_get_bus:= SafeGetProcAddress(libgst, 'gst_element_get_bus');
|
||||
gst_mini_object_unref:= SafeGetProcAddress(libgst, 'gst_mini_object_unref');
|
||||
gst_element_set_state:= SafeGetProcAddress(libgst, 'gst_element_set_state');
|
||||
gst_element_factory_make:= SafeGetProcAddress(libgst, 'gst_element_factory_make');
|
||||
gst_bus_timed_pop_filtered:= SafeGetProcAddress(libgst, 'gst_bus_timed_pop_filtered');
|
||||
|
||||
Result:= gst_init_check(nil, nil, @AError);
|
||||
|
||||
if not Result then
|
||||
begin
|
||||
AMsg:= AError^.message;
|
||||
g_error_free(AError);
|
||||
raise Exception.Create(AMsg);
|
||||
end;
|
||||
except
|
||||
on E: Exception do
|
||||
begin
|
||||
Result:= False;
|
||||
DebugLn(E.Message);
|
||||
FreeLibrary(libgst);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
|
@ -132,6 +132,8 @@ var
|
|||
libsdl: TLibHandle;
|
||||
|
||||
function SDL_Initialize: Boolean;
|
||||
var
|
||||
AMsg: String;
|
||||
begin
|
||||
libsdl:= SafeLoadLibrary(sdllib);
|
||||
Result:= (libsdl <> NilHandle);
|
||||
|
|
@ -148,6 +150,14 @@ begin
|
|||
SDL_OpenAudioDevice:= SafeGetProcAddress(libsdl, 'SDL_OpenAudioDevice');
|
||||
SDL_PauseAudioDevice:= SafeGetProcAddress(libsdl, 'SDL_PauseAudioDevice');
|
||||
SDL_CloseAudioDevice:= SafeGetProcAddress(libsdl, 'SDL_CloseAudioDevice');
|
||||
|
||||
Result:= SDL_InitSubSystem(SDL_INIT_AUDIO) = 0;
|
||||
|
||||
if not Result then
|
||||
begin
|
||||
AMsg:= SDL_GetError();
|
||||
raise Exception.Create(AMsg);
|
||||
end;
|
||||
except
|
||||
on E: Exception do
|
||||
begin
|
||||
|
|
|
|||
|
|
@ -15,6 +15,9 @@ uses
|
|||
, CocoaAll, uMyDarwin
|
||||
{$ELSE}
|
||||
, LazLogger, sdl2
|
||||
{$IFNDEF HAIKU}
|
||||
, gst
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
;
|
||||
|
||||
|
|
@ -69,25 +72,28 @@ begin
|
|||
end;
|
||||
{$ELSE}
|
||||
const
|
||||
Res: Integer = -1;
|
||||
First: Boolean = True;
|
||||
Play: function(const FileName: String): Boolean = nil;
|
||||
begin
|
||||
if First then
|
||||
begin
|
||||
{$IF NOT DEFINED(HAIKU)}
|
||||
if GST_Initialize then
|
||||
begin
|
||||
Play:= @GST_Play;
|
||||
end
|
||||
else
|
||||
{$ENDIF}
|
||||
if SDL_Initialize then
|
||||
begin
|
||||
Res:= SDL_InitSubSystem(SDL_INIT_AUDIO);
|
||||
if (Res < 0) then
|
||||
begin
|
||||
DebugLn('SDL_InitSubSystem: ', SDL_GetError());
|
||||
end;
|
||||
Play:= @SDL_Play;
|
||||
end;
|
||||
First:= False;
|
||||
end;
|
||||
if (Res < 0) then
|
||||
if (Play = nil) then
|
||||
Result:= False
|
||||
else begin
|
||||
Result:= SDL_Play(FileName);
|
||||
Result:= Play(FileName);
|
||||
end;
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue