External C-Libary and Events

Post

Posted
Rating:
#1 (In Topic #1033)
Regular
JumpyVB is in the usergroup ‘Regular’
Forum member Vuott introduced me to libvlc. I quite like it and managed to succesfully add a function (specifically libvlc_media_player_set_time) to the extern interface. But how can I hook with the events provided by the library such as libvlc_MediaPlayerTimeChangedhttps://videolan.video…503d3558b9117550e8d3c9259? I would like to avoid use of the repeat until loop.

Here's the sample code:

Code (gambas)

  1. Private m As Pointer Library "libvlc:5.6.0"
  2.  
  3. ' enum libvlc_state_t
  4. Private Enum libvlc_NothingSpecial = 0, libvlc_Opening, libvlc_Buffering, libvlc_Playing, libvlc_Paused, libvlc_Stopped, libvlc_Ended, libvlc_Error
  5. ' enum libvlc_video_orient_t
  6. Private Enum libvlc_video_orient_top_left = 0, libvlc_video_orient_top_right, libvlc_video_orient_bottom_left, libvlc_video_orient_bottom_right, libvlc_video_orient_left_top, libvlc_video_orient_left_bottom, libvlc_video_orient_right_top, libvlc_video_orient_right_bottom
  7.  
  8. ' Create And initialize a libvlc instance.
  9. Private Extern libvlc_new(argc As Integer, argv As String[]) As Pointer
  10. ' Create a media for a certain file path.
  11. Private Extern libvlc_media_new_path(p_instance As Pointer, path As String) As Pointer
  12. ' Create a Media Player object from a Media.
  13. Private Extern libvlc_media_player_new_from_media(p_md As Pointer) As Pointer
  14. ' Set an X Window System drawable where the media player should render its video output.
  15. Private Extern libvlc_media_player_set_xwindow(p_mi As Pointer, drawable As Integer)
  16. ' Play the video file.
  17. Private Extern libvlc_media_player_play(p_mi As Pointer) As Integer
  18. ' Stop the video file
  19. Private Extern libvlc_media_player_stop(p_mi As Pointer)
  20. ' Get the current movie length (in ms).
  21. Private Extern libvlc_media_player_get_length(p_mi As Pointer, l_ex As Pointer) As Integer
  22. ' Get the current movie time (in ms).
  23. Private Extern libvlc_media_player_get_time(p_mi As Pointer) As Integer
  24. ' Get current movie state.
  25. Private Extern libvlc_media_player_get_state(p_mi As Pointer) As Integer
  26. ' Toggle breaks.
  27. Private Extern libvlc_media_player_pause(p_mi As Pointer)
  28. ' Release a media_player after use Decrement the reference count of a media player object.
  29. Private Extern libvlc_media_player_release(p_mi As Pointer)
  30. ' Decrement the reference count of a media descriptor object.
  31. Private Extern libvlc_media_release(p_md As Pointer)
  32. ' Decrement the reference count of a libvlc instance, and destroy it if it reaches zero.
  33. Private Extern libvlc_release(p_instance As Pointer)
  34. 'Set the movie time (in ms)
  35. Private Extern libvlc_media_player_set_time(p_mi As Pointer, i_time As Long, b_fast As Boolean) As Integer
  36.  
  37. Public Sub ButtonPlay_Click()
  38. ' Initialize the VLC library
  39.   inst = libvlc_new(0, Null)
  40. ' Create a new multimedia object.
  41.   m = libvlc_media_new_path(inst, "/home/user/Videos/first_vid.mp4")
  42. ' Create a media player
  43.   mp = libvlc_media_player_new_from_media(m)
  44. ' To show the video in the "DrawingArea", we get his identifier
  45.   Dim id As Integer = DrawingArea1.Id
  46. ' We pass the identifier of the window, in which the video must be shown
  47.   libvlc_media_player_set_xwindow(mp, id)
  48. ' Starts the execution of the video file by the media player :
  49.   libvlc_media_player_play(mp)
  50.  
  51.  ' Repeat
  52.  '   TextLabel1.Text = "Durata: " & Str(Time(0, 0, 0, libvlc_media_player_get_length(mp, 0)))
  53.  '   TextLabel2.Text = "<font color=red>" & Str(Time(0, 0, 0, libvlc_media_player_get_time(mp))) & "</font>"
  54.  '   Wait 0.01
  55.  ' Until libvlc_media_player_get_state(mp) > libvlc_Paused
  56.  '
  57.  ' Chiude()
  58.  
  59.  
  60. Public Sub ButtonSeek_Click()
  61.   libvlc_media_player_set_time(mp, 2000, False)
  62. Public Sub ToggleButtonPause_Click()
  63.   libvlc_media_player_pause(mp)
  64. Public Sub ButtonStop_Click()
  65.   libvlc_media_player_stop(mp)
  66.   'Closes the VLC library
  67.   libvlc_media_player_release(mp)
  68.   libvlc_media_release(m)
  69.   libvlc_release(inst)
Online now: No Back to the top

Post

Posted
Rating:
#2
Regular
vuott is in the usergroup ‘Regular’

JumpyVB said

how can I hook with the events provided by the library such as libvlc_MediaPlayerTimeChanged
The elements of the "libvlc_event_e " Enumeration appear to be intertwined :? with the "libvlc_event_attach() " function, the "libvlc_event_t " Enumeration, and a "<COLOR color="#BF0000">callback</COLOR>" loop and its specific functions.
I have no experience with that in VLC.
Bad bargain !   :|

…or maybe you could use a Timer.

Europaeus sum !

<COLOR color="#FF8000">Amare memorentes atque deflentes ad mortem silenter labimur.</COLOR>
Online now: No Back to the top

Post

Posted
Rating:
#3
Regular
JumpyVB is in the usergroup ‘Regular’

vuott said

The elements of the "libvlc_event_e " Enumeration appear to be intertwined :? with the "libvlc_event_attach() " function, the "libvlc_event_t " Enumeration, and a "<COLOR color="#BF0000">callback</COLOR>" loop and its specific functions. I have no experience with that in VLC. Or maybe you could use a Timer.

Yeas a timer could do the trick. Thank you for the idea.

Also I will consider investigating further (externing events for the libvlc) myself. Making use of c libraries from Gambas has been on my todo list (despite c language seems very daunting). But do you have previous experience of interfacing some other c library with events? If you can confirm it could be possible I would know it's not a lost cause? A link to a gambas example with any extern events would help tremendously.

PS: My home videos are working fine now in libvlc as opposed to gstreamer. I am experiencing none of that non responsivenes at the end of the video.
Online now: No Back to the top

Post

Posted
Rating:
#4
Regular
vuott is in the usergroup ‘Regular’

JumpyVB said

But do you have previous experience of interfacing some other c library with events?
Usually Events in C programs are handled with loops or "callbacks" calls.
For handling "callback" calls, using external resources in Gambas, you can have a look at this section "Function Callbacks" in the following official Wiki page:

   /lang/extdecl - Gambas Documentation

Europaeus sum !

<COLOR color="#FF8000">Amare memorentes atque deflentes ad mortem silenter labimur.</COLOR>
Online now: No Back to the top

Post

Posted
Rating:
#5
Regular
JumpyVB is in the usergroup ‘Regular’
I will gradually post stuff that makes this better. I will start with this:

Code (gambas)

  1. Private Extern XInitThreads() As Integer In "libX11"
Call this function before "libvlc_new(0, Null)" to get rid of error "Xlib not initialized for threads".

Source for the information was found here: https://forum.videolan.org/viewtopic.php?t=136443
Online now: No Back to the top

Post

Posted
Rating:
#6
Regular
JumpyVB is in the usergroup ‘Regular’
I think I'm getting close to having events working with this code:

Code (gambas)

  1. ' Gambas class file
  2.  
  3. Private Extern XInitThreads() As Integer In "libX11"
  4.  
  5. Private m As Pointer Library "libvlc:5.6.0"
  6. Private Extern libvlc_new(argc As Integer, argv As String[]) As Pointer
  7. Private Extern libvlc_media_new_path(p_instance As Pointer, path As String) As Pointer
  8. Private Extern libvlc_media_player_new_from_media(p_md As Pointer) As Pointer
  9. Private Extern libvlc_media_player_set_xwindow(p_mi As Pointer, drawable As Integer)
  10. Private Extern libvlc_media_player_play(p_mi As Pointer) As Integer
  11. Private Extern libvlc_media_player_stop(p_mi As Pointer)
  12. Private Extern libvlc_media_player_get_length(p_mi As Pointer, l_ex As Pointer) As Integer
  13. Private Extern libvlc_media_player_get_time(p_mi As Pointer) As Integer
  14. Private Extern libvlc_media_player_get_state(p_mi As Pointer) As Integer
  15. Private Extern libvlc_media_player_pause(p_mi As Pointer)
  16. Private Extern libvlc_media_player_release(p_mi As Pointer)
  17. Private Extern libvlc_media_release(p_md As Pointer)
  18. Private Extern libvlc_release(p_instance As Pointer)
  19. Private Extern libvlc_media_player_set_time(p_mi As Pointer, i_time As Long, b_fast As Boolean) As Integer
  20.  
  21. '# Events
  22. Private event_manager As Pointer
  23. '# Get the Event Manager from which the media player send event.
  24. Private Extern libvlc_media_player_event_manager(p_mi As Pointer) As Pointer
  25. '# Register for an event notification.
  26. Private Extern libvlc_event_attach(p_event_manager As Pointer, i_event_type As Integer, f_callback As Pointer, user_data As Pointer) As Integer
  27. '# enum libvlc_event_e [https://github.com/videolan/libvlcsharp/blob/3.x/src/LibVLCSharp/Shared/LibVLCEvents.cs]
  28. Private Enum MediaMetaChanged = 0, MediaSubItemAdded = 1, MediaDurationChanged = 2, MediaParsedChanged = 3, MediaFreed = 4, MediaStateChanged = 5, MediaSubItemTreeAdded = 6, MediaPlayerMediaChanged = 256, MediaPlayerNothingSpecial = 257, MediaPlayerOpening = 258, MediaPlayerBuffering = 259, MediaPlayerPlaying = 260, MediaPlayerPaused = 261, MediaPlayerStopped = 262, MediaPlayerForward = 263, MediaPlayerBackward = 264, MediaPlayerEndReached = 265, MediaPlayerEncounteredError = 266, MediaPlayerTimeChanged = 267, MediaPlayerPositionChanged = 268, MediaPlayerSeekableChanged = 269, MediaPlayerPausableChanged = 270, MediaPlayerTitleChanged = 271, MediaPlayerSnapshotTaken = 272, MediaPlayerLengthChanged = 273, MediaPlayerVout = 274, MediaPlayerScrambledChanged = 275, MediaPlayerESAdded = 276, MediaPlayerESDeleted = 277, MediaPlayerESSelected = 278, MediaPlayerCorked = 279, MediaPlayerUncorked = 280, MediaPlayerMuted = 281, MediaPlayerUnmuted = 282, MediaPlayerAudioVolume = 283, MediaPlayerAudioDevice = 284, MediaPlayerChapterChanged = 285, MediaListItemAdded = 512, MediaListWillAddItem = 513, MediaListItemDeleted = 514, MediaListWillDeleteItem = 515, MediaListEndReached = 516, MediaListViewItemAdded = 768, MediaListViewWillAddItem = 769, MediaListViewItemDeleted = 770, MediaListViewWillDeleteItem = 771, MediaListPlayerPlayed = 1024, MediaListPlayerNextItemSet = 1025, MediaListPlayerStopped = 1026
  29. '# typedef void( * libvlc_callback_t)(const struct libvlc_event_t * p_event, void * p_data)
  30. Public Struct Libvlc_event_t
  31.   type As Integer
  32.   p_obj As Pointer
  33. End Struct
  34. Public Sub callback(p_event As Libvlc_event_t, p_data As Pointer)
  35.   Me.Text = "Event fired"
  36.  
  37. Public Sub ButtonPlay_Click()
  38.   XInitThreads() '# https://forum.videolan.org/viewtopic.php?t=136443
  39.   inst = libvlc_new(0, Null)
  40.   m = libvlc_media_new_path(inst, "/home/user/Videos/first_vid.mp4")
  41.   mp = libvlc_media_player_new_from_media(m)
  42.   event_manager = libvlc_media_player_event_manager(mp)
  43.   libvlc_event_attach(event_manager, MediaPlayerPaused, callback, Null)
  44.   Dim id As Integer = DrawingArea1.Id
  45.   libvlc_media_player_set_xwindow(mp, id)
  46.   libvlc_media_player_play(mp)
  47.  
  48. Public Sub ToggleButtonPause_Click()
  49.   libvlc_media_player_pause(mp)
The vlc event manager tries to call the callback-function when video is paused but gambas will crash with a segmentation fault. I think it's this part that needs to be fixed:

Code (gambas)

  1. Public Struct Libvlc_event_t
  2.   type As Integer
  3.   p_obj As Pointer
  4. End Struct
  5. Public Sub callback(p_event As Libvlc_event_t, p_data As Pointer)
  6.   Me.Text = "Event fired"
p_event is some kind of struct https://videolan.video…lc__events_8h_source.html but I am having trouble defining it in Gambas. But I don't really need the information stored in the struct. Is there a way to fool libvlc to just write that data to oblivion and be able to continue without crashing?
Online now: No Back to the top

Post

Posted
Rating:
#7
Regular
vuott is in the usergroup ‘Regular’
:? Opsss…I saw your last two posts only today.
Anyway, I was able to eliminate the error when clicking on the "ToggleButton" to pause the video file.
I made the following changes.

1) The Structure "Libvlc_event_t" of the VLC library contains, as a third member a "Union" that occupies 16 bytes. In the Structure, which you reproduced in Gambas, I simply declared that third member as a "Pointer".
Here it is:

Code (gambas)

  1. Public Struct Libvlc_event_t
  2.   type As Integer
  3.   p_obj As Pointer
  4.   u As Pointer
  5. End Struct

2) It is also necessary to add the external function "libvlc_event_detach()" in the routine "ToggleButtonPause_Click()", when pausing the execution of the video file (it should be placed after the external function "libvlc_media_player_pause()"); as well as to call up the external function "libvlc_event_attach()". when resuming the execution of the video after pausing.

3) In addition, it was necessary to correctly arrange the command lines within the routine "Public Sub ToggleButtonPause_Click()".

4) Here is the :? new piece of code:

Code (gambas)

  1. .......
  2. Private Extern libvlc_event_detach(p_event_manager As Pointer, i_event_type As Integer, f_callback As Pointer, user_data As Pointer) As Integer
  3. ......
  4.  
  5.  
  6. Public Sub callback(p_event As Libvlc_event_t, p_data As Pointer)
  7.  
  8.  
  9.  
  10. Public Sub Button1_Click()
  11.   XInitThreads() '# https://forum.videolan.org/viewtopic.php?t=136443
  12.   inst = libvlc_new(0, Null)
  13.   m = libvlc_media_new_path(inst, "/path/of/video/file")
  14.   mp = libvlc_media_player_new_from_media(m)
  15.   event_manager = libvlc_media_player_event_manager(mp)
  16.   libvlc_event_attach(event_manager, MediaPlayerPaused, callback, Null)
  17.   Dim id As Integer = DrawingArea1.Id
  18.   libvlc_media_player_set_xwindow(mp, id)
  19.   libvlc_media_player_play(mp)
  20.  
  21. Public Sub ToggleButtonPause_Click()
  22.  
  23.   If ToggleButtonPause.Value Then
  24.     libvlc_media_player_pause(mp)
  25.     libvlc_event_detach(event_manager, MediaPlayerPaused, callback, Null)
  26.   Else
  27.     libvlc_event_attach(event_manager, MediaPlayerPaused, callback, Null)
  28.     libvlc_media_player_play(mp)
  29.  

5) Now it works !   :)

Europaeus sum !

<COLOR color="#FF8000">Amare memorentes atque deflentes ad mortem silenter labimur.</COLOR>
Online now: No Back to the top

Post

Posted
Rating:
#8
Regular
JumpyVB is in the usergroup ‘Regular’

vuott said

Now it works!
I can confirm. Thank you.
Online now: No Back to the top
1 guest and 0 members have just viewed this.