LVC 播放器buffer自定義讀寫的方法
阿新 • • 發佈:2019-01-27
LVC 播放器提供buffer自定義讀寫的方法,但是並沒有開放到Java層,並且關於此類的應用也並不多;不過用到的也很少;下面就簡單介紹應用的方法:
在LVC 中的lvc\lib\media.c中已經提供其應用介面,介面如下:
libvlc_media_t *libvlc_media_new_callbacks(libvlc_instance_t *p_instance,
libvlc_media_open_cb open_cb,
libvlc_media_read_cb read_cb,
libvlc_media_seek_cb seek_cb,
libvlc_media_close_cb close_cb,
void *opaque);
簡單的使用方法就是在lvclibjni_media.c 實現其jni的介面;方法如下:
static int opaque;
static bool isFifoReadStop = false;
int media_open_cb(void *opaque, void **datap,uint64_t *sizep)
{
<pre name="code" class="objc">printf("%s", __FUNCTION__);
return 0;}ssize_t media_read_cb(void *opaque, unsigned char *buf, size_t len){ int readLen = 0; int oneLen = 0; void *p_read_buffer = NULL; readLen = 0;while(isFifoReadStop == false){ oneLen = getFifobuf(&p_read_buffer,len - readLen); if(oneLen
> 0) { memcpy(buf+readLen,p_read_buffer,oneLen); readLen += oneLen; } if(readLen >= len) { break; }} if(isFifoReadStop != false) { return -1; } //printf("read:%ld byte ~ %ld byte\n",readLen,len); if((readLen <= 0) ||(readLen > len)) { printf("media_read_cb no data or stop read len = %d get len = %d\n",readLen,len); readLen = 0; return -1; } return (ssize_t)readLen;}void media_close_cb(void *opaque){printf("media_read_cb stop read data\n");
}int media_seek_cb(void *opaque, uint64_t offset){ return 0;}voidJava_org_videolan_libvlc_Media_nativeNewFromBufferCallBack(JNIEnv *env, jobject thiz, jobject libVlc){ vlcjni_object *p_obj; int fd = (*env)->GetIntField(env, jfd, fields.FileDescriptor.descriptorID); if ((*env)->ExceptionOccurred(env)) { (*env)->ExceptionClear(env); fd = -1; } if (fd == -1) { throw_IllegalArgumentException(env, "fd invalid"); return; } p_obj = VLCJniObject_newFromJavaLibVlc(env, thiz, libVlc); if (!p_obj) return; p_obj->u.p_m = libvlc_media_new_callbacks(p_obj->p_libvlc, media_open_cb, media_read_cb, media_close_cb, media_seek_cb, &opaque); Media_nativeNewCommon(env, thiz, p_obj);} 在media.java中實現呼叫//printf("%s", __FUNCTION__);
private native void nativeNewFromBufferCallBack(LibVLC libVLC);
public Media(LibVLC libVLC) {
nativeNewFromBufferCallBack(libVLC);
}
如果,不希望在jni中實現資料的讀取介面,則可以在Java中實現,在回撥函式中呼叫Java類中實現的介面即可,此次略過;
實現的另外一種方法,是不通過更改media的jni,而通過更改mediaplay jni來更改media的引數即可;
方法如下:
#include <android/log.h>
#include <vlc/libvlc.h>
#include <vlc/libvlc_media.h>
#include <vlc/libvlc_media_list.h> // For the subitems, here for convenience
#include <vlc/libvlc_events.h>
#include <vlc_common.h>
#include <vlc_input.h>
#include <vlc_meta.h>
#include <vlc_playlist.h> /* For the preparser */
#include <vlc_url.h>
#include "libvlc_internal.h"
#include "media_internal.h"
#include "Fifobuf.h"
....
void
Java_org_videolan_libvlc_MediaPlayer_nativeSetMediaBufferCallback(JNIEnv *env,
jobject thiz,
jobject jmedia)
{
libvlc_media_t *p_m = NULL;
vlcjni_object *p_obj = VLCJniObject_getInstance(env, thiz);
if (!p_obj)
return;
if (jmedia)
{
vlcjni_object *p_m_obj = VLCJniObject_getInstance(env, jmedia);
if (!p_m_obj)
return;
p_m = p_m_obj->u.p_m;
LOGI("register media buffer callback\n");
input_item_AddOpaque(p_m->p_input_item, "imem-data", opaque);
input_item_AddOpaque(p_m->p_input_item, "imem-open", media_open_cb);
input_item_AddOpaque(p_m->p_input_item, "imem-read", media_read_cb);
input_item_AddOpaque(p_m->p_input_item, "imem-seek", media_seek_cb);
input_item_AddOpaque(p_m->p_input_item, "imem-close", media_close_cb);
}
}
Java實現如下:
private native void nativeSetMediaBufferCallback(Media media);
public void setSetMediaBufferCallback(Media media)
{
nativeSetMediaBufferCallback(media);
}
呼叫方法不變,但是引數需要更改為:
String playUrl = "imem://";
Uri uri = Uri.parse(playUrl);
if(mMedia != null)
{
mMedia.release();
}
mMedia = new Media(libvlc, uri);
mVlcPlayer.setSetMediaBufferCallback(mMedia);
mVlcPlayer.setMedia(mMedia);