1

我正在尝试使用该libvlc_media_new_callbacks功能使用 libvlc 从内存中播放媒体。此函数需要指向四个回调函数的指针:OpenReadSeekClose

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)

如果我不指定回调Read,则Seek、 和回调都可以正常工作,但这意味着 libvlc 不会知道媒体的长度。CloseOpen

当我指定一个Open回调时,它会使用正确的opaque参数调用,但其他回调会获得一个空指针。这使得无法知道回调应该在哪个流上工作。

我是否误解了 open 回调的目的?

这是我的回调函数:

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
4

1 回答 1

2

根据文档,您必须分配一个缓冲区并在 open 的 Buffer 参数中返回其地址(为此,您需要将其更改为 ByRef 参数!)。然后,您将获得在其他函数中传递的相同缓冲区 ptr。

理想情况下,你会设置

Buffer = r

在 MediaOpen 中。但是Xojo不会让你。相反,您需要维护一个字典,在其中存储r然后将其与您可以分配给 Buffer 参数的值相关联。

这是一个示例(未测试):

Static Property OpenedBuffers as Dictionary
Static Property OpenedBufferID as Integer

Shared Function MediaOpen(Opaque As Ptr, ByRef HandleOut As Integer, ByRef BufferSize As UInt64) As UInt32
  Dim r As BinaryStream = Streams.Lookup(Opaque, Nil)
  If r = Nil Then Return 1 ' invalid Opaque
  if OpenedBuffers = nil then OpenedBuffers = new Dictionary
  OpenedBufferID = OpenedBufferID + 1
  OpenedBuffers.Value(OpenedBufferID) = r
  HandleOut = OpenedBufferID
  BufferSize = r.Length
  Return 0
End Function

Shared Function MediaRead(Handle As Integer, Buffer As Ptr, BufferSize As Integer) As UInt32
  Dim r As BinaryStream = OpenedBuffers.Value(Handle)
  ...

Shared Sub MediaClose(Handle As Integer)
  Dim r As BinaryStream = OpenedBuffers.Value(Handle)
  OpenedBuffers.Remove (Handle)
  If Streams.HasKey(r) Then Streams.Remove(r)
  ...

希望有帮助

于 2018-05-02T19:59:11.470 回答