I'm trying to use the libvlc_media_new_callbacks function to play media from memory using libvlc. This function expects pointers to four callback functions: Open, Read, Seek, and Close.
Declare Function libvlc_media_new_callbacks Lib "libvlc.dll" (Instance As Ptr, OpenCB As Ptr, ReadCB As Ptr, SeekCB As Ptr, CloseCB As Ptr, Opaque As Ptr) As Ptr
Dim opaque As Ptr = SomeOpaqueValue()
Dim handle As Ptr = libvlc_media_new_callbacks(instance, AddressOf MediaOpen, AddressOf MediaRead, AddressOf MediaSeek, AddressOf MediaClose, opaque)
The Read, Seek, and Close callbacks all work fine if I don't specify an Open callback but that means libvlc won't know how long the media is.
When I do specify an Open callback it gets invoked with the correct opaque parameter but the other callbacks get a null pointer instead. This makes it impossible to know which stream the callback should be working on.
Have I misunderstood the purpose of the open callback?
Here are my callback functions:
Shared Function MediaOpen(Opaque As Ptr, Buffer As Ptr, ByRef BufferSize As UInt64) As UInt32
Dim r As BinaryStream = Streams.Lookup(Opaque, Nil)
If r = Nil Then Return 1 ' invalid Opaque
Buffer = Nil ' Not sure what to do with this parameter
BufferSize = r.Length
Return 0
End Function
Shared Sub MediaClose(Opaque As Ptr)
If Streams.HasKey(Opaque) Then Streams.Remove(Opaque)
If Streams.Count = 0 Then Streams = Nil
End Sub
Shared Function MediaRead(Opaque As Ptr, Buffer As Ptr, BufferSize As Integer) As UInt32
Dim r As BinaryStream = Streams.Lookup(Opaque, Nil)
If r = Nil Then Return 0 ' invalid Opaque
Dim mb As MemoryBlock = Buffer
Dim data As MemoryBlock = r.Read(BufferSize)
mb.StringValue(0, data.Size) = data
Return data.Size
End Function
Shared Function MediaSeek(Opaque As Ptr, Offset As UInt64) As Int32
Dim r As BinaryStream = Streams.Lookup(Opaque, Nil)
If r = Nil Then Return 1 ' invalid Opaque
If Offset > r.Length Then Return 1 ' invalid offset
r.Position = Offset
Return 0
End Function
According to the docs, you have to allocate a buffer and return its address in the open's Buffer parameter (you need to change it into a ByRef parm for that!). Then you'll get that same buffer ptr passed in the other functions.
Ideally, you'd set
in MediaOpen. But Xojo won't let you. Instead, you need to maintain a Dictionary in which you store
rand then associate that with a value you can assign to the Buffer parm.Here's an example (not tested):
Hope that helps