linux下编译vlc for android 添加 截图(去掉了画中画和路径提示)及录像功能

时间:2022-03-20 15:55:23

最近的项目中用到了视频播放及录像功能,因而下了一个vlc4android编译。这一纪录一下编译环境配置和编译过程中遇到的问题。


1.环境配置

      debian3.2.4 amd64

      android-sdk-linux  ( 22.6)

      android-ndk-r9d

      具体过程见:

     https://wiki.videolan.org/AndroidCompile/ 


      


  2.编译过程出现的问题

   2.1

(cd speex-git && patch -fp1) < ../../contrib/src/speex/no-ogg.patch
patching file configure.ac
Hunk #1 FAILED at 112.
1 out of 1 hunk FAILED -- saving rejects to file configure.ac.rej
patching file libspeex/Makefile.am
Hunk #1 FAILED at 11.
1 out of 1 hunk FAILED -- saving rejects to file libspeex/Makefile.am.rej
patching file src/Makefile.am
Hunk #1 FAILED at 11.
Hunk #2 FAILED at 24.
2 out of 2 hunks FAILED -- saving rejects to file src/Makefile.am.rej
make: *** [speex] Error 1


解决方法:在该网站http://downloads.videolan.org/contrib/ 下载speex-git.tar.gz放在vlc/contrib/tarballs目录下覆盖掉原来的speex-git.tar.gz文件。



2.2

make[3]: Leaving directory `/home/wxx/newvlc/android/vlc/contrib/android/gmp/mpn'
make[2]: *** [install-recursive] Error 1
make[2]: Leaving directory `/home/wxx/newvlc/android/vlc/contrib/android/gmp'
make[1]: *** [install] Error 2
make[1]: Leaving directory `/home/wxx/newvlc/android/vlc/contrib/android/gmp'




tmp-udiv.s: Assembler messages:
 tmp-udiv.s:85: Error: ARM register expected -- `str r1,[ r0 ]'
 tmp-udiv.s:136: Error: ARM register expected -- `str r1,[ r0 ]'


上面这两个错误致错原因是一样的,解决方法:

  将下面这个patch文件放在vlc/contrib/android/gmp目录下,例如保存命名为ggmp.diff

--- a/mpn/arm/udiv.asm
+++ b/mpn/arm/udiv.asm
@@ -48,7 +48,7 @@ L(oop): divstep(n1,n0,d)
teq r12, #0
bne L(oop)

- str n1, [ rem_ptr ] C store remainder
+ str n1, [rem_ptr] C store remainder
adc r0, n0, n0 C quotient: add last carry from divstep
bx lr

@@ -87,7 +87,7 @@ L(oop2):
addcs n0, n0, #1 C adjust quotient

L(_even_divisor):
- str n1, [ rem_ptr ] C store remainder
+ str n1, [rem_ptr] C store remainder
mov r0, n0 C quotient
ldmfd sp!, { r8, pc }
EPILOGUE(mpn_udiv_qrnnd)

然后在该目录执行  patch -p1 < ggmp.diff即可。


2.3 

configure: error: libavcodec versions 56 and later are not supported yet.
/home/wxx/android/android-ndk-r9d/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: .././vlc/contrib/arm-linux-androideabi/lib/libavcodec.a(opusdec.o): in function opus_decode_packet:libavcodec/opusdec.c:377: error: undefined reference to 'avresample_is_open'
/home/wxx/android/android-ndk-r9d/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: .././vlc/contrib/arm-linux-androideabi/lib/libavcodec.a(opusdec.o): in function


libavcodec versions 55 and later are not supported yet


出现上面的两个错误是因为最近(2014/08/05号附近)ffmpeg又更新了,添加了一些函数,与其他库不匹配,单独下一个低版本的就可以了。我也会提供一个供大家下载。 (因为tarballs下的包一旦编成库,只要包名没变,就不会重编,因此建议删掉tarballs下所有包后,将ffmpeg-HEAD包放入,再次执行sh compile.sh)

最好的方法是更改vlc/contrib/src/ffmpeg该目录下rules.mak的FFMPEG_SNAPURL值。

2.4  

c compiler cannot create executables

这个错误很可能是sdk 或 ndk 的版本错了(32/64),不过我未作验证。


添加录像功能的patch文件链接https://patches.videolan.org/patch/606/,放在vlc目录下保存为xxx.diff,然后执行 patch -p1 < xxx.diff。可能有的地方不成功,自行添加即可。

在jni/libvlcjni.c后面添加函数:

  

jboolean Java_org_videolan_libvlc_LibVLC_takeSnapShot(JNIEnv *env, jobject thiz,jint number, jstring path, jint width,jint height)
{
jboolean isCopy;
libvlc_media_player_t *mp = getMediaPlayer(env, thiz);
/* Get C string */
const char* psz_path = (*env)->GetStringUTFChars(env, path, &isCopy);

if (mp)
if(libvlc_video_take_snapshot(mp, (int)number,psz_path , (int)width,(int)height)==0)
return JNI_TRUE;
return JNI_FALSE;

}


jboolean Java_org_videolan_libvlc_LibVLC_videoRecordStart(JNIEnv *env, jobject thiz,jstring path)
{
jboolean isCopy;
libvlc_media_player_t *mp = getMediaPlayer(env, thiz);
/* Get C string */
const char* psz_path = (*env)->GetStringUTFChars(env, path, &isCopy);
//const char* psz_filename=(*env)->GetStringUTFChars(env, filename, &isCopy);
if (mp)
if(libvlc_media_player_record_start(mp,psz_path)==0)
return JNI_TRUE;
return JNI_FALSE;
}

jboolean Java_org_videolan_libvlc_LibVLC_videoRecordStop(JNIEnv *env, jobject thiz)
{
jboolean isCopy;
libvlc_media_player_t *mp = getMediaPlayer(env, thiz);
/* Get C string */
if (mp)
if(libvlc_media_player_record_stop(mp)==0)
return JNI_TRUE;
return JNI_FALSE;
}

jboolean Java_org_videolan_libvlc_LibVLC_videoIsRecording(JNIEnv *env, jobject thiz)
{
jboolean isCopy;
libvlc_media_player_t *mp = getMediaPlayer(env, thiz);
if (mp)
if(libvlc_media_player_is_recording(mp))
return JNI_TRUE;
return JNI_FALSE;
}
jboolean Java_org_videolan_libvlc_LibVLC_videoIsRecordable(JNIEnv *env, jobject thiz)
{
jboolean isCopy;
libvlc_media_player_t *mp = getMediaPlayer(env, thiz);
if (mp)
if(libvlc_media_player_is_recordable(mp))
return JNI_TRUE;
return JNI_FALSE;
}

jint Java_org_videolan_libvlc_LibVLC_getState(JNIEnv *env, jobject thiz)
{
libvlc_media_player_t *mp = getMediaPlayer(env, thiz);
if (mp){
libvlc_state_t state=libvlc_media_player_get_state(mp);
return (jint)state;
}
else
return -1;
}

然后在LibVLC.java中添加接口:

    public native boolean takeSnapShot( int num, String file, int width, int height);

public native boolean videoRecordStart(String path);

public native boolean videoRecordStop();

public native boolean videoIsRecording();

public native boolean videoIsRecordable();

public native int getState();

public boolean takeSnapShot(String file, int width, int height) {
return takeSnapShot(0, file, width, height);
}

刚在提到的截图时去掉画中画和路径提示,只需要在vlc/src/vout_intf.c的VoutSaveSnapshot函数中注释掉

   

VoutOsdSnapshot( p_vout, p_picture, psz_filename );

就可以了。


参考:http://bbs.csdn.net/topics/390671446

              https://dev.openwrt.org/ticket/14231

              https://patches.videolan.org/patch/606/


资料下载:

            http://download.csdn.net/detail/wxxgreat/7748425