android视频播放器-源码

合集下载

Android开发—SeeJoPlayer视频播放器源码解析

Android开发—SeeJoPlayer视频播放器源码解析

2020.03.27 v1.2.0 beta版:更新说明:一、完美支持android1.五、android1.六、android2.0、android2.0一、android2.1平台;2、完美支持320×480、480×800、480×854等各类分辨率(自适应屏幕分辨率);3、支持在线音视频播放,支持URL input和从浏览器调用SeeJoPlayer播放器播放在线音视频;4、自动转为横屏播放,为用户提供更好的观看体验;5、修改了没有SD卡程序出错的Bug;6、美化了视频播放列表和操作说明的界面。

第一部份:功能介绍SeeJoPlayer的优势要紧在相对还算美观的界面和便利的交互操作上。

先说操作吧,它支持:一、全屏切换: 双击屏幕二、播放/暂停: 长按屏幕3、静音/恢复: 长按音量按钮4、播放列表: 操纵面板最右边的按钮(暂不支持编辑功能)五、音量调剂: 单击音量按钮,在弹出的音量显示区域触摸改变音量这些操作和PC上的播放器较为类似,希望大伙儿能用得适应。

至于界面的话,多说无益,直接上图吧:第二部份:源码解析一、VideoView与视频比例缩放:咱们能够很方便的取得VideoView的源代码,最简单的方式是直接在上找“.java”。

因此重写VideoView的进程其实只是在原先的基础上进行一些修改罢了,并非一个很麻烦的工作。

什么缘故Android自带的VideoView会维持视频的长宽比而不能让咱们很方便的自概念比例呢?我猜想可能Google 做Android也是一个很仓促的工程,许多代码并无考虑得太成熟。

VideoView的源码中有如此一段代码:1 @Override2 3 4 5 6 7 8 9101112131415161718192021222324252627protectedvoid onMeasure(int widthMeasureSpec, int heightMeasureSpec){//Log.i("@@@@", "onMeasure");int width = getDefaultSize(mVideoWidth, widthMeasureSpec);int height = getDefaultSize(mVideoHeight, heightMeasureSpec);if(mVideoWidth >0&& mVideoHeight >0){if( mVideoWidth * height > width * mVideoHeight ){//Log.i("@@@", "image too tall, correcting");height = width * mVideoHeight / mVideoWidth;}elseif( mVideoWidth * height < width * mVideoHeight ){//Log.i("@@@", "image too wide, correcting");width = height * mVideoWidth / mVideoHeight;}else{//Log.i("@@@", "aspect ratio is correct: " +//width+"/"+height+"="+//mVideoWidth+"/"+mVideoHeight);}}//Log.i("@@@@@@@@@@", "setting size: " + width + 'x' + height); setMeasuredDimension(width, height);}这确实是什么缘故长宽比不能改变的缘故了。

基于Android的视频播放器的设计与实现

基于Android的视频播放器的设计与实现

基于Android的视频播放器的设计与实现基于Android的视频播放器的设计与实现中文摘要如今,随着基于Android操作系统的智能手机的广泛应用,视频播放器已成为智能手机的一个必不可少的程序,广大用户迫切需要一个贴近用户、方便用户、个性化的视频播放器。

因此,设计一个基于android手机的多功能播放器,具有重要的实际意义。

本次毕业设计主要使用JDK + Eclipse + Android-SDK-Windows工具进行开发,使用的编程语言是Java语言。

该程序主要由4个不同Activity来实现,每个Activity实现相应的功能模块,能够有效满足Android手机用户在视频播放中的常见需求。

本论文详细介绍了播放器程序的设计思路、设计方案、系统结构和项目工程结构,对系统的可行性与需求性进行了详细的分析,阐述了系统各个模块功能的设计与实现。

对程序主要的Activity都进行了详细的介绍和分析,包括对其使用的布局文件的具体介绍,以及各个控件的作用。

在最后进行了程序测试,对每一个实现的模块功能都做了测试,并且记录了大量截图用来展示测试结果,以观察程序应有的功能是否正常运行,以及发现程序中可能存在的问题。

所开发的程序界面比较友好,操作相对容易,达到设计要求。

关键词:安卓;视频播放;Activity;MediaplayerThe Design and Implementation of Video Player Based on AndroidABSTRACTNow, with the wide application of smart phone based on the Android operating system, video player has become the essential application of smart phone. Most of consumers urgently require a personalized video player which is close to user and facilitate user. Therefore, the design of a multifunctional player based on android mobile phones has an important practical significance.The project design is developed by using JDK, Eclipse, and Android-SDK-Windows tools. The programming language is Java. The program consists of four different Activities and each Activity achieves the corresponding functional modules which can effectively satisfy the common requirements for playing video on Android mobile phones.This paper introduced the design ideas, design scheme, system architecture and project engineering structures of video player. The feasibility and requirements of system were analyzed in detail. The system function and each module were explained. The main Activity of the program are described and analyzed in detail including the using layout file, as well as the role of each control. Finally, I made the test for the program including the functions of each implemented modules. In order to observe whether the program should function properly and find the problems that may exist in the program, many screenshots were saved to demonstrate the test results. The developed program has a friendly interface and can be operated relatively easy, which has achieved the design requirement.KEY WORDS: Android; Video Play; Activity; Mediaplayer目录中文摘要 ...................................................................... ABSTRACT ...................................................................... 目录 (I)第一章绪论 01.1课题的来源及意义 01.2 ANDROID发展现状及前景 01.3项目的主要工作和解决的问题 (1)1.4系统设计的目标及基本思路 (2)1.5论文组织结构 (2)第二章 ANDROID视频播放器相关技术介绍 (3)2.1 ANDROID介绍 (3)2.2 ANDROID开发平台及相关技术 (4)2.2.1 ANDROID-WINDOWS开发环境 (4)2.2.2 MEDIAPLAYER视频技术 (5)2.2.3 SURFACE、SURFACEVIEW、SURFACEHOLDER三者之间的关系 (8)第三章系统分析及系统结构设计与实现 (10)3.1系统分析 (10)3.1.1系统可行性分析 (10)3.1.2 系统需求分析 (10)3.2系统结构设计 (11)第四章测试 (16)4.1测试环境和条件 (16)4.2测试 (16)4.3测试结果分析 (25)结论 (27)参考文献 (28)附录 (30)第一章绪论1.1课题的来源及意义在这个信息化的时代,IT业已经成为世界发展的主流,我们对信息技术的依赖远远超过了对我们自己的依赖,计算机和手机已经成为我们日常生活中不可缺少的获得信息的渠道。

Android视频播放器(四):使用ExoPlayer播放视频

Android视频播放器(四):使用ExoPlayer播放视频

Android视频播放器(四):使⽤ExoPlayer播放视频⼀、简介ExoPlayer是⼀个Android应⽤层的媒体播放器,它提供了⼀套可替换Android MediaPlayer的API,可以播放本地或者是线上的⾳视频资源。

ExoPlayer⽀持⼀些Android MediaPlayer不⽀持的特性,⽐如适配DASH和SmoothStreaming的播放。

和MediaPlayer不同的是,ExoPlayer 很容易⾃定义和扩展,并且它可以通过应⽤商店的应⽤程序更新来直接更新。

现在在Android设备上播放视频和⾳乐的应⽤是⼀个很热门的应⽤,Android框架提供的MediaPlayer可以使⽤很少的代码量快速的实现播放⾳视频的功能,⽽且它也提供了底层的API⽐如MediaCodec、AudioTrack和MediaDrm,它们同样可以创建⾃定义媒体播放器,⽽ExoPlayer 是建⽴在底层⾳视频API之上的开源的应⽤级媒体播放器。

优点对于Android内置的MediaPlayer来说,ExoPlayer有以下⼏个优点:1. ⽀持DASH和SmoothStreaming这两种数据格式的资源,⽽MediaPlayer对这两种数据格式都不⽀持。

它还⽀持其它格式的数据资源,⽐如MP4, M4A, FMP4, WebM, MKV, MP3, Ogg, WAV, MPEG-TS, MPEG-PS, FLV and ADTS (AAC)等2. ⽀持⾼级的HLS特性,⽐如能正确的处理#EXT-X-DISCONTINUITY标签3. ⽆缝连接,合并和循环播放多媒体的能⼒4. 和应⽤⼀起更新播放器(ExoPlayer),因为ExoPlayer是⼀个集成到应⽤APK⾥⾯的库,你可以决定你所想使⽤的ExoPlayer版本,并且可以随着应⽤的更新把ExoPlayer更新到⼀个最新的版本。

5. 较少的关于设备的特殊问题,并且在不同的Android版本和设备上很少会有不同的表现。

Android本地视频播放器开发--SDL编译

Android本地视频播放器开发--SDL编译

Android本地视频播放器开发--SDL编译其实1.3以后的版本就添加了android的支持,所以下载完源码后,在SDL目录下创建一个jni的目录,然后将原先SDL目录下面的文件以及文件夹都拷贝到jni目录下面,在jni目录下面我们会看见一个android.mk的文件,这就是官方给我们编写的编译文件,由于手机基本上都是使用的arm编译器,所以我在里面添加了LOCAL_ARM_MODE=arm,模块的编译使用arm编译器来编译,具体的内容如下:[cpp] ############################# SDL shared library############################include $(CLEAR_VARS)LOCAL_MODULE := SDL2LOCAL_ARM_MODE=armLOCAL_C_INCLUDES := $(LOCAL_PATH)/includeLOCAL_SRC_FILES := \$(subst $(LOCAL_PATH)/,, \$(wil dcard $(LOCAL_PATH)/src/*.c) \$(wil dcard $(LOCAL_PATH)/src/audio/*.c) \$(wil dcard $(LOCAL_PATH)/src/audio/android/*.c) \$(wil dcard $(LOCAL_PATH)/src/audio/dummy/*.c) \$(LOCAL_PATH)/src/atomic/SDL_atomic.c \$(LOCAL_PATH)/src/atomic/SDL_spinl ock.c.arm \$(wil dcard $(LOCAL_PATH)/src/core/android/*.cpp) \$(wil dcard $(LOCAL_PATH)/src/cpuinfo/*.c) \$(wil dcard $(LOCAL_PATH)/src/events/*.c) \$(wil dcard $(LOCAL_PATH)/src/fil e/*.c) \$(wil dcard $(LOCAL_PATH)/src/haptic/*.c) \$(wil dcard $(LOCAL_PATH)/src/haptic/dummy/*.c) \$(wil dcard $(LOCAL_PATH)/src/joystick/*.c) \$(wil dcard $(LOCAL_PATH)/src/joystick/android/*.c) \$(wil dcard $(LOCAL_PATH)/src/l oadso/dl open/*.c) \ $(wil dcard $(LOCAL_PATH)/src/power/*.c) \ $(wil dcard $(LOCAL_PATH)/src/power/android/*.c) \ $(wil dcard $(LOCAL_PATH)/src/render/*.c) \ $(wil dcard $(LOCAL_PATH)/src/render/*/*.c) \ $(wil dcard $(LOCAL_PATH)/src/stdlib/*.c) \$(wil dcard $(LOCAL_PATH)/src/thread/*.c) \ $(wil dcard $(LOCAL_PATH)/src/thread/pthread/*.c) \ $(wil dcard $(LOCAL_PATH)/src/timer/*.c) \$(wil dcard $(LOCAL_PATH)/src/timer/unix/*.c) \ $(wil dcard $(LOCAL_PATH)/src/video/*.c) \$(wil dcard $(LOCAL_PATH)/src/video/android/*.c)) LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES LOCAL_LDLIBS := -l dl -lGLESv1_CM -lGLESv2 -ll og include $(BUILD_SHARED_LIBRARY)############################# SDL shared library############################include $(CLEAR_VARS)LOCAL_MODULE := SDL2LOCAL_ARM_MODE=armLOCAL_C_INCLUDES := $(LOCAL_PATH)/include LOCAL_SRC_FILES := \$(subst $(LOCAL_PATH)/,, \$(wil dcard $(LOCAL_PATH)/src/*.c) \$(wil dcard $(LOCAL_PATH)/src/audio/*.c) \$(wil dcard $(LOCAL_PATH)/src/audio/android/*.c) \ $(wil dcard $(LOCAL_PATH)/src/audio/dummy/*.c) \ $(LOCAL_PATH)/src/atomic/SDL_atomic.c \$(LOCAL_PATH)/src/atomic/SDL_spinl ock.c.arm \$(wil dcard $(LOCAL_PATH)/src/core/android/*.cpp) \$(wil dcard $(LOCAL_PATH)/src/cpuinfo/*.c) \$(wil dcard $(LOCAL_PATH)/src/events/*.c) \$(wil dcard $(LOCAL_PATH)/src/fil e/*.c) \$(wil dcard $(LOCAL_PATH)/src/haptic/*.c) \$(wil dcard $(LOCAL_PATH)/src/haptic/dummy/*.c) \$(wil dcard $(LOCAL_PATH)/src/joystick/*.c) \$(wil dcard $(LOCAL_PATH)/src/joystick/android/*.c) \$(wil dcard $(LOCAL_PATH)/src/l oadso/dl open/*.c) \$(wil dcard $(LOCAL_PATH)/src/power/*.c) \$(wil dcard $(LOCAL_PATH)/src/power/android/*.c) \$(wil dcard $(LOCAL_PATH)/src/render/*.c) \$(wil dcard $(LOCAL_PATH)/src/render/*/*.c) \$(wil dcard $(LOCAL_PATH)/src/stdlib/*.c) \$(wil dcard $(LOCAL_PATH)/src/thread/*.c) \$(wil dcard $(LOCAL_PATH)/src/thread/pthread/*.c) \$(wil dcard $(LOCAL_PATH)/src/timer/*.c) \$(wil dcard $(LOCAL_PATH)/src/timer/unix/*.c) \$(wil dcard $(LOCAL_PATH)/src/video/*.c) \$(wil dcard $(LOCAL_PATH)/src/video/android/*.c))LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPESLOCAL_LDLIBS := -l dl -lGLESv1_CM -lGLESv2 -ll oginclude $(BUILD_SHARED_LIBRARY)三、如果直接编译的话会提示如下错误[cpp] /home/SDL/jni/src/core/android/SDL_android.cpp:30:21: fatal error: EGL/egl.h: No such fil e or directory/home/SDL/jni/src/core/android/SDL_android.cpp:30:21: fatal error: EGL/egl.h: No such fil e or directory查看EGL的支持是在2.3版本以上,所以我们需要添加平台的支持,所以需要在jni目录下面创建一个Application.mk文件来指定编译平台,内容如下:[cpp] APP_ABI := armeabiAPP_PLATFORM := android-9APP_ABI := armeabiAPP_PLATFORM := android-9四、在jni目录终端下运行ndk-buil d,就会编译出libSDL2.so,编译过程如下:[cpp] root@zhangjie:/home/SDL/jni# ndk-buil dCompil e arm : SDL2 <= SDL_assert.cCompil e arm : SDL2 <= SDL.cCompil e arm : SDL2 <= SDL_error.cCompil e arm : SDL2 <= SDL_fatal.cCompil e arm : SDL2 <= SDL_hints.cCompil e arm : SDL2 <= SDL_l og.cCompil e arm : SDL2 <= SDL_audio.cCompil e arm : SDL2 <= SDL_audiocvt.cCompil e arm : SDL2 <= SDL_audiodev.cCompil e arm : SDL2 <= SDL_audiotypecvt.cCompil e arm : SDL2 <= SDL_mixer.cCompil e arm : SDL2 <= SDL_wave.cCompil e arm : SDL2 <= SDL_androidaudio.cCompil e arm : SDL2 <= SDL_dummyaudio.cCompil e arm : SDL2 <= SDL_atomic.cCompil e arm : SDL2 <= SDL_spinl ock.cCompil e++ arm : SDL2 <= SDL_android.cppCompil e arm : SDL2 <= SDL_cpuinfo.cCompil e arm : SDL2 <= SDL_clipboard events.cCompil e arm : SDL2 <= SDL_dropevents.cCompil e arm : SDL2 <= SDL_events.cCompil e arm : SDL2 <= SDL_gesture.cCompil e arm : SDL2 <= SDL_keyboard.cCompil e arm : SDL2 <= SDL_mouse.cCompil e arm : SDL2 <= SDL_quit.cCompil e arm : SDL2 <= SDL_touch.cCompil e arm : SDL2 <= SDL_windowevents.cCompil e arm : SDL2 <= SDL_rwops.cCompil e arm : SDL2 <= SDL_haptic.c Compil e arm : SDL2 <= SDL_syshaptic.c Compil e arm : SDL2 <= SDL_gamecontroll er.c Compil e arm : SDL2 <= SDL_joystick.c Compil e arm : SDL2 <= SDL_sysjoystick.c Compil e arm : SDL2 <= SDL_sysl oadso.c Compil e arm : SDL2 <= SDL_power.c Compil e arm : SDL2 <= SDL_syspower.c Compil e arm : SDL2 <= SDL_render.c Compil e arm : SDL2 <= SDL_yuv_mmx.c Compil e arm : SDL2 <= SDL_yuv_sw.c Compil e arm : SDL2 <= SDL_render_d3d.c Compil e arm : SDL2 <= SDL_render_gl es2.c Compil e arm : SDL2 <= SDL_shaders_gl es2.c Compil e arm : SDL2 <= SDL_render_gl es.c Compil e arm : SDL2 <= SDL_render_gl.c Compil e arm : SDL2 <= SDL_shaders_gl.c Compil e arm : SDL2 <= SDL_render_psp.c Compil e arm : SDL2 <= SDL_bl endfillrect.c Compil e arm : SDL2 <= SDL_bl endline.c Compil e arm : SDL2 <= SDL_bl endpoint.c Compil e arm : SDL2 <= SDL_drawline.c Compil e arm : SDL2 <= SDL_drawpoint.c Compil e arm : SDL2 <= SDL_render_sw.c Compil e arm : SDL2 <= SDL_rotate.c Compil e arm : SDL2 <= SDL_getenv.c Compil e arm : SDL2 <= SDL_iconv.c Compil e arm : SDL2 <= SDL_mall oc.c Compil e arm : SDL2 <= SDL_qsort.c Compil e arm : SDL2 <= SDL_stdlib.c Compil e arm : SDL2 <= SDL_string.cCompil e arm : SDL2 <= SDL_thread.cCompil e arm : SDL2 <= SDL_syscond.c Compil e arm : SDL2 <= SDL_sysmutex.c Compil e arm : SDL2 <= SDL_syssem.c Compil e arm : SDL2 <= SDL_systhread.c Compil e arm : SDL2 <= SDL_timer.cCompil e arm : SDL2 <= SDL_systimer.c Compil e arm : SDL2 <= SDL_blit_0.cCompil e arm : SDL2 <= SDL_blit_1.cCompil e arm : SDL2 <= SDL_blit_A.cCompil e arm : SDL2 <= SDL_blit_auto.c Compil e arm : SDL2 <= SDL_blit.cCompil e arm : SDL2 <= SDL_blit_copy.c Compil e arm : SDL2 <= SDL_blit_N.cCompil e arm : SDL2 <= SDL_blit_sl ow.c Compil e arm : SDL2 <= SDL_bmp.cCompil e arm : SDL2 <= SDL_clipboard.c Compil e arm : SDL2 <= SDL_fillrect.cCompil e arm : SDL2 <= SDL_pixels.cCompil e arm : SDL2 <= SDL_rect.cCompil e arm : SDL2 <= SDL_RLEaccel.c Compil e arm : SDL2 <= SDL_shape.cCompil e arm : SDL2 <= SDL_stretch.cCompil e arm : SDL2 <= SDL_surface.c Compil e arm : SDL2 <= SDL_video.cCompil e arm : SDL2 <= SDL_androidclipboard.c Compil e arm : SDL2 <= SDL_android events.c Compil e arm : SDL2 <= SDL_androidgl.c Compil e arm : SDL2 <= SDL_androidkeyboard.c Compil e arm : SDL2 <= SDL_androidtouch.c Compil e arm : SDL2 <= SDL_androidvideo.cCompil e arm : SDL2 <= SDL_androidwind ow.c StaticLibrary : libstdc++.aSharedLibrary : libSDL2.soInstall : libSDL2.so => libs/armeabi/libSDL2.so root@zhangjie:/home/SDL/jni# ndk-buil dCompil e arm : SDL2 <= SDL_assert.cCompil e arm : SDL2 <= SDL.cCompil e arm : SDL2 <= SDL_error.cCompil e arm : SDL2 <= SDL_fatal.cCompil e arm : SDL2 <= SDL_hints.cCompil e arm : SDL2 <= SDL_l og.cCompil e arm : SDL2 <= SDL_audio.cCompil e arm : SDL2 <= SDL_audiocvt.cCompil e arm : SDL2 <= SDL_audiodev.cCompil e arm : SDL2 <= SDL_audiotypecvt.c Compil e arm : SDL2 <= SDL_mixer.cCompil e arm : SDL2 <= SDL_wave.cCompil e arm : SDL2 <= SDL_androidaudio.c Compil e arm : SDL2 <= SDL_dummyaudio.c Compil e arm : SDL2 <= SDL_atomic.cCompil e arm : SDL2 <= SDL_spinl ock.cCompil e++ arm : SDL2 <= SDL_android.cpp Compil e arm : SDL2 <= SDL_cpuinfo.cCompil e arm : SDL2 <= SDL_clipboard events.c Compil e arm : SDL2 <= SDL_dropevents.cCompil e arm : SDL2 <= SDL_events.cCompil e arm : SDL2 <= SDL_gesture.cCompil e arm : SDL2 <= SDL_keyboard.cCompil e arm : SDL2 <= SDL_mouse.cCompil e arm : SDL2 <= SDL_quit.cCompil e arm : SDL2 <= SDL_touch.cCompil e arm : SDL2 <= SDL_windowevents.c Compil e arm : SDL2 <= SDL_rwops.c Compil e arm : SDL2 <= SDL_haptic.c Compil e arm : SDL2 <= SDL_syshaptic.c Compil e arm : SDL2 <= SDL_gamecontroll er.c Compil e arm : SDL2 <= SDL_joystick.c Compil e arm : SDL2 <= SDL_sysjoystick.c Compil e arm : SDL2 <= SDL_sysl oadso.c Compil e arm : SDL2 <= SDL_power.c Compil e arm : SDL2 <= SDL_syspower.c Compil e arm : SDL2 <= SDL_render.c Compil e arm : SDL2 <= SDL_yuv_mmx.c Compil e arm : SDL2 <= SDL_yuv_sw.c Compil e arm : SDL2 <= SDL_render_d3d.c Compil e arm : SDL2 <= SDL_render_gl es2.c Compil e arm : SDL2 <= SDL_shaders_gl es2.c Compil e arm : SDL2 <= SDL_render_gl es.c Compil e arm : SDL2 <= SDL_render_gl.c Compil e arm : SDL2 <= SDL_shaders_gl.c Compil e arm : SDL2 <= SDL_render_psp.c Compil e arm : SDL2 <= SDL_bl endfillrect.c Compil e arm : SDL2 <= SDL_bl endline.c Compil e arm : SDL2 <= SDL_bl endpoint.c Compil e arm : SDL2 <= SDL_drawline.c Compil e arm : SDL2 <= SDL_drawpoint.c Compil e arm : SDL2 <= SDL_render_sw.c Compil e arm : SDL2 <= SDL_rotate.c Compil e arm : SDL2 <= SDL_getenv.c Compil e arm : SDL2 <= SDL_iconv.c Compil e arm : SDL2 <= SDL_mall oc.c Compil e arm : SDL2 <= SDL_qsort.cCompil e arm : SDL2 <= SDL_stdlib.cCompil e arm : SDL2 <= SDL_string.cCompil e arm : SDL2 <= SDL_thread.cCompil e arm : SDL2 <= SDL_syscond.c Compil e arm : SDL2 <= SDL_sysmutex.c Compil e arm : SDL2 <= SDL_syssem.c Compil e arm : SDL2 <= SDL_systhread.c Compil e arm : SDL2 <= SDL_timer.cCompil e arm : SDL2 <= SDL_systimer.c Compil e arm : SDL2 <= SDL_blit_0.cCompil e arm : SDL2 <= SDL_blit_1.cCompil e arm : SDL2 <= SDL_blit_A.cCompil e arm : SDL2 <= SDL_blit_auto.c Compil e arm : SDL2 <= SDL_blit.cCompil e arm : SDL2 <= SDL_blit_copy.c Compil e arm : SDL2 <= SDL_blit_N.cCompil e arm : SDL2 <= SDL_blit_sl ow.c Compil e arm : SDL2 <= SDL_bmp.cCompil e arm : SDL2 <= SDL_clipboard.c Compil e arm : SDL2 <= SDL_fillrect.cCompil e arm : SDL2 <= SDL_pixels.cCompil e arm : SDL2 <= SDL_rect.cCompil e arm : SDL2 <= SDL_RLEaccel.c Compil e arm : SDL2 <= SDL_shape.cCompil e arm : SDL2 <= SDL_stretch.cCompil e arm : SDL2 <= SDL_surface.c Compil e arm : SDL2 <= SDL_video.cCompil e arm : SDL2 <= SDL_androidclipboard.c Compil e arm : SDL2 <= SDL_android events.c Compil e arm : SDL2 <= SDL_androidgl.c Compil e arm : SDL2 <= SDL_androidkeyboard.cCompil e arm : SDL2 <= SDL_androidtouch.cCompil e arm : SDL2 <= SDL_androidvideo.cCompil e arm : SDL2 <= SDL_androidwind ow.cStaticLibrary : libstdc++.aSharedLibrary : libSDL2.soInstall: libSDL2.so => libs/armeabi/libSDL2.so编译出sdl库后,我们就可以调用它的相关函数来实现我们的功能了。

基于android平台的视频播放器设计论文

基于android平台的视频播放器设计论文

基于android平台的视频播放器设计论文四川理工学院毕业设计基于android平台的视频播放器设计学生:徐东学号:12021040122专业:电气工程及其自动化班级:2012.卓越指导教师:曾晓辉、刘兴忠四川理工学院自动化与电子信息学院二O一六年六徐东:基于Android平台的视频播放器设计摘要:随着计算机科学和移动终端的不断发展,Android移动在终端已经成为了当今的主流,功能完善和性能优越的移动设备是用户优先选择的。

因此开发出功能强大且界面美观的手机应用具有广阔的市场前景。

本视频播放器是基于Android平台研究开发,具有完善美观的用户界面,除了基本的播放视频外,还能查看视频信息,视频的进度条的拖拽,手势调节屏幕亮度和声音大小。

本文设计的播放器采用Vitamio的视频解码器框架,可以播放多种常见的本地视频格式,界面简洁美观。

关键词:Android,Vitamio,视频,播放器四川理工学院本科毕业设计Abstract:With the continuous development of computer science and mobile terminals, Android mobile terminal has become the mainstream of today's mainstream, functional improvement and superior performance of mobile devices is the user preferred. So it has a broad market prospect to develop the mobile phone with powerful function and beautiful interface.The video player is based on Android platform research and development, with a perfect and beautiful user interface, in addition to the basic play video, but also to see the video information, the progress of the video of the drag, gesture control screen brightness and loudness of the sounds.In this paper, the design of the player using Vitamio video decoder framework, you can play a variety of common video format, the interface is simple and beautiful.Key words: Android,Vitamio,Video ,player目录第1章前言1.1设计的目的及意义随着当今科学技术的发展, 各种各样的应用被安装到移动电话上,比如视频电话,VOD视频,移动上网冲浪,在线阅读和资料共享等。

android视频播放器源码

android视频播放器源码

1.mian.xml代码<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="/apk/res/android"android:layout_width="fill_parent"android:layout_height="fill_parent"android:orientation="vertical" ><TextViewandroid:id="@+id/textview"android:layout_width="fill_parent"android:layout_height="wrap_content"android:text="@string/filename"/><EditTextandroid:id="@+id/filename"android:layout_width="fill_parent"android:layout_height="wrap_content"android:text="yueshen.mp4"/><SurfaceViewandroid:id="@+id/surfaceView"android:layout_width="fill_parent"android:layout_height="300dp"/><SeekBarandroid:id="@+id/move"android:layout_width="fill_parent"android:layout_height="wrap_content"/><LinearLayoutandroid:layout_width="fill_parent"android:layout_height="wrap_content"android:orientation="horizontal" ><ImageButtonandroid:id="@+id/play"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/play"android:layout_weight="1"/><ImageButtonandroid:id="@+id/suspend"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/suspend"android:layout_weight="1"/><ImageButtonandroid:id="@+id/reset"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/reset"android:layout_weight="1"/><ImageButtonandroid:id="@+id/stop"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/stop"android:layout_weight="1"/><ImageButtonandroid:id="@+id/back"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/back"android:layout_weight="1"/><ImageButtonandroid:id="@+id/quick"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/quick"android:layout_weight="1"/><ImageButtonandroid:id="@+id/exit"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/exit"android:layout_weight="1"/></LinearLayout></LinearLayout>2.Activity_main.java代码package com.example.videoplayer;import java.io.File;import java.io.IOException;import android.media.AudioManager;import android.media.MediaPlayer;import android.os.Bundle;import android.os.Environment;import android.app.Activity;import android.util.Log;import android.view.Menu;import android.view.SurfaceHolder;import android.view.SurfaceView;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.ImageButton;import android.widget.SeekBar;import android.widget.Toast;import android.widget.SeekBar.OnSeekBarChangeListener; public class ZhaoActivity extends Activity {private static final String TAG="ZhaoActivity";private EditText filenameText;private String filename;private MediaPlayer mediaPlayer;private SurfaceView surfaceView;//private SeekBar seekbar;@SuppressWarnings("deprecation")@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(yout.main);filenameText=(EditText)this.findViewById(R.id.filename);mediaPlayer=new MediaPlayer();surfaceView=(SurfaceView)this.findViewById(R.id.surfaceView);surfaceView.getHolder().setFixedSize(176, 144);//设置分辨率surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);ButtonClickListener listener = new ButtonClickListener();ImageButton playButton =(ImageButton)this.findViewById(R.id.play);ImageButton susButton =(ImageButton)this.findViewById(R.id.suspend);ImageButton resetButton =(ImageButton)this.findViewById(R.id.reset);ImageButton stopButton =(ImageButton)this.findViewById(R.id.stop);ImageButton exitButton =(ImageButton)this.findViewById(R.id.exit);ImageButton quickButton =(ImageButton)this.findViewById(R.id.quick);ImageButton backButton =(ImageButton)this.findViewById(R.id.back);SeekBar seekbar=(SeekBar)this.findViewById(R.id.move);playButton.setOnClickListener(listener);susButton.setOnClickListener(listener);resetButton.setOnClickListener(listener);stopButton.setOnClickListener(listener);exitButton.setOnClickListener(listener);quickButton.setOnClickListener(listener);backButton.setOnClickListener(listener);seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {@Overridepublic void onStopTrackingTouch(SeekBar arg0) {// TODO Auto-generated method stub}@Overridepublic void onStartTrackingTouch(SeekBar arg0) {// TODO Auto-generated method stub}@Overridepublic void onProgressChanged(SeekBar seekBar, int progcess, boolean fromUser) {// TODO Auto-generated method stubint process = seekBar.getProgress();int max = seekBar.getMax();if (mediaPlayer != null) {mediaPlayer.seekTo(mediaPlayer.getDuration() * process / max);}}});}private final class ButtonClickListener implements View.OnClickListener{@Overridepublic void onClick(View v) {// TODO Auto-generated method stubif(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {Toast.makeText(ZhaoActivity.this, R.string.sdcarderror, 1).show();return;}filename=filenameText.getText().toString();try {switch(v.getId()){case R.id.play:play();break;case R.id.suspend:if(mediaPlayer.isPlaying()){mediaPlayer.pause();}else{mediaPlayer.start();}break;case R.id.reset:if(mediaPlayer.isPlaying()){mediaPlayer.seekTo(0);}else{play();}break;case R.id.quick:if(mediaPlayer.isPlaying()){int i=mediaPlayer.getCurrentPosition()+5000;mediaPlayer.seekTo(i);}break;case R.id.back:if(mediaPlayer.isPlaying()){int i=mediaPlayer.getCurrentPosition()-5000;mediaPlayer.seekTo(i);}break;case R.id.stop:if(mediaPlayer.isPlaying()){mediaPlayer.stop();}break;case R.id.exit:mediaPlayer.release();//释放资源finish();break;}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();Log.e(TAG, e.toString());}}}private void play() throws IOException {File videoFile = new File(Environment.getExternalStorageDirectory(),filename);mediaPlayer.reset();//重置为初始状态mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);mediaPlayer.setDisplay(surfaceView.getHolder());if(!videoFile.exists()){Toast.makeText(ZhaoActivity.this, R.string.fileerror, 1).show();return;}mediaPlayer.setDataSource(videoFile.getAbsolutePath());mediaPlayer.prepare();//缓冲mediaPlayer.start();//播放}}。

AndroidGSYVideoPlayer视频播放器功能的实现

AndroidGSYVideoPlayer视频播放器功能的实现

AndroidGSYVideoPlayer视频播放器功能的实现GSYVideoPlayerGSYVideoPlayer ⼀个基于IJkPlayer的播放器⽀持调节声⾳亮度边播边缓存使⽤了AndroidVideoCache;ExoPlayer使⽤SimpleCache⽀持多种协议h263\4\5、Https、concat、rtsp、hls、rtmp、crypto、mpeg等等简单滤镜(马赛克、⿊⽩、⾊彩过滤、⾼斯、模糊、模糊等等20多种)、动画、(⽔印、画⾯多重播放等)视频第⼀帧、视频帧截图功能,视频⽣成gif功能。

调整显⽰⽐例:默认、16:9、4:3、填充;播放时旋转画⾯⾓度(0,90,180,270);镜像旋转IJKPlayer、EXOPlayer、MediaPlayer切换、⾃定义内核⼩窗⼝、多窗体下(包括桌⾯)的⼩窗⼝播放。

⽚头⼴告、跳过⼴告⽀持、中间插⼊⼴告功能。

暂停前后台切换不⿊屏;调整不同清晰度的⽀持;⽆缝切换⽀持;锁定/解锁全屏点击功能;进度条⼩窗⼝预览可⾃定义渲染层、⾃定义管理层、⾃定义播放层(控制层)、⾃定义缓存层使⽤依赖1、JCenter 引⼊⽅法(推荐)你可以选择下⾯三种的其中⼀种,在module下的build.gradle添加。

A、直接引⼊//完整版引⼊implementation 'com.shuyu:GSYVideoPlayer:8.1.2'B、添加java和你想要的so⽀持:implementation 'com.shuyu:gsyVideoPlayer-java:8.1.2'//是否需要ExoPlayer模式implementation 'com.shuyu:GSYVideoPlayer-exo2:8.1.2'//根据你的需求ijk模式的soimplementation 'com.shuyu:gsyVideoPlayer-armv5:8.1.2'implementation 'com.shuyu:gsyVideoPlayer-armv7a:8.1.2'implementation 'com.shuyu:gsyVideoPlayer-arm64:8.1.2'implementation 'com.shuyu:gsyVideoPlayer-x64:8.1.2'implementation 'com.shuyu:gsyVideoPlayer-x86:8.1.2'C、⽀持其他格式协议的(mpeg,rtsp, concat、crypto协议)implementation 'com.shuyu:gsyVideoPlayer-java:8.1.2'//是否需要ExoPlayer模式implementation 'com.shuyu:GSYVideoPlayer-exo2:8.1.2'//更多ijk的编码⽀持implementation 'com.shuyu:gsyVideoPlayer-ex_so:8.1.2'代码中的全局切换⽀持//EXOPlayer内核,⽀持格式更多PlayerFactory.setPlayManager(Exo2PlayerManager.class);//系统内核模式PlayerFactory.setPlayManager(SystemPlayerManager.class);//ijk内核,默认模式PlayerFactory.setPlayManager(IjkPlayerManager.class);//exo缓存模式,⽀持m3u8,只⽀持exoCacheFactory.setCacheManager(ExoPlayerCacheManager.class);//代理缓存模式,⽀持所有模式,不⽀持m3u8等,默认CacheFactory.setCacheManager(ProxyCacheManager.class);//切换渲染模式GSYVideoType.setShowType(GSYVideoType.SCREEN_MATCH_FULL);//默认显⽰⽐例GSYVideoType.SCREEN_TYPE_DEFAULT = 0;//16:9GSYVideoType.SCREEN_TYPE_16_9 = 1;//4:3GSYVideoType.SCREEN_TYPE_4_3 = 2;//全屏裁减显⽰,为了显⽰正常 CoverImageView 建议使⽤FrameLayout作为⽗布局GSYVideoType.SCREEN_TYPE_FULL = 4;//全屏拉伸显⽰,使⽤这个属性时,surface_container建议使⽤FrameLayoutGSYVideoType.SCREEN_MATCH_FULL = -4;/**** SCREEN_TYPE_CUSTOM 下⾃定义显⽰⽐例* @param screenScaleRatio ⾼宽⽐,如 16:9*/public static void setScreenScaleRatio(float screenScaleRatio)//切换绘制模式GSYVideoType.setRenderType(GSYVideoType.SUFRACE);GSYVideoType.setRenderType(GSYVideoType.GLSURFACE);GSYVideoType.setRenderType(GSYVideoType.TEXTURE);//ijk关闭logIjkPlayerManager.setLogLevel(IjkMediaPlayer.IJK_LOG_SILENT);//exoplayer⾃定义MediaSourceExoSourceManager.setExoMediaSourceInterceptListener(new ExoMediaSourceInterceptListener() {@Overridepublic MediaSource getMediaSource(String dataSource, boolean preview, boolean cacheEnable, boolean isLooping, File cacheDir) {//可⾃定义MediaSourcereturn null;}});⾃定义⼀个播放器public class LiveVideo extends StandardGSYVideoPlayer {public LiveDataFullscreenButtonClick liveDataClick;//点击全屏按钮回调/*** 恢复暂停状态*/public void onResume() {onVideoResume();}/*** 暂停状态*/public void onPause() {onVideoPause();}/*** 接⼝回调* @param liveDataClick*/public void setOnFullscreenButtonClick(LiveDataFullscreenButtonClick liveDataClick) { this.liveDataClick = liveDataClick;}/* 重写⽅法⾃定义layout id与video_layout_standard.xml⼀致不重新使⽤系统默认布局*/ @Overridepublic int getLayoutId() {return yout.test;}public LiveVideo(Context context, Boolean fullFlag) {super(context, fullFlag);init();}public LiveVideo(Context context) {super(context);init();}public LiveVideo(Context context, AttributeSet attrs) {super(context, attrs);init();}/* 初始化操作 */private void init() {//EXOPlayer内核,⽀持格式更多// PlayerFactory.setPlayManager(Exo2PlayerManager.class);//代理缓存模式,⽀持所有模式,不⽀持m3u8等,默认// CacheFactory.setCacheManager(ProxyCacheManager.class);//系统内核模式// PlayerFactory.setPlayManager(SystemPlayerManager.class);//ijk内核,默认模式PlayerFactory.setPlayManager(IjkPlayerManager.class);settingsVideo();}/* ⼀些播放器的设置做⼀些UI的隐藏可根据⾃⼰需求*/public void settingsVideo() {GSYVideoType.enableMediaCodec();//使能硬解码,播放前设置Debuger.enable();//打开GSY的Log//隐藏⼀些UIsetViewShowState(mBottomContainer, VISIBLE);setViewShowState(mTopContainer, VISIBLE);setViewShowState(mLockScreen, GONE);setViewShowState(mLoadingProgressBar, GONE);setViewShowState(mTopContainer, GONE);setViewShowState(mThumbImageView, GONE);setViewShowState(mBottomProgressBar, GONE);//显⽰⼀些UI 进度时间当前时间全屏返回加载Loading 暂停开始setViewShowState(mStartButton, VISIBLE);setViewShowState(mLoadingProgressBar, VISIBLE);setViewShowState(mFullscreenButton, VISIBLE);setViewShowState(mBackButton, GONE);setViewShowState(mProgressBar, VISIBLE);setViewShowState(mCurrentTimeTextView, VISIBLE);setViewShowState(mTotalTimeTextView, VISIBLE);setEnlargeImageRes(R.drawable.full);setShrinkImageRes(R.drawable.full);}//拦截事件@Overridepublic boolean dispatchTouchEvent(MotionEvent ev) {mFullscreenButton.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View view) {liveDataClick.onClick();}});return super.dispatchTouchEvent(ev);}/* 取消双击暂停 */@Overrideprotected void touchDoubleUp() {// super.touchDoubleUp();}public interface LiveDataFullscreenButtonClick {void onClick();}}<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@android:color/black"><RelativeLayoutandroid:id="@+id/surface_container"android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"></RelativeLayout><RelativeLayoutandroid:id="@+id/thumb"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_alignParentBottom="true"android:layout_alignParentEnd="true"android:layout_alignParentLeft="true"android:layout_alignParentRight="true"android:layout_alignParentStart="true"android:layout_alignParentTop="true"android:background="#000000"android:scaleType="fitCenter" /><LinearLayoutandroid:id="@+id/layout_bottom"android:layout_width="match_parent"android:layout_height="40dp"android:layout_alignParentBottom="true"android:background="#99000000"android:gravity="center_vertical"android:orientation="horizontal"android:visibility="invisible"><TextViewandroid:id="@+id/current"android:textColor="@color/white"style="@style/news_des_style"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="16dp"android:text="00:00"/><SeekBarandroid:id="@+id/progress"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_gravity="center_vertical"android:layout_weight="1.0"android:background="@null"android:padding="10dp"android:max="100"android:maxHeight="4dp"android:minHeight="4dp"android:paddingBottom="8dp"android:paddingTop="8dp"android:progressDrawable="@drawable/video_progress_bg" android:thumb="@drawable/video_seek_thumb" /><TextViewandroid:id="@+id/total"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginRight="16dp"android:text="00:00"android:textColor="@color/white"style="@style/news_des_style"/></LinearLayout><LinearLayoutandroid:id="@+id/layout_top"android:layout_width="match_parent"android:layout_height="48dp"android:background="@drawable/video_title_bg"android:gravity="center_vertical"><ImageViewandroid:id="@+id/back"android:layout_width="48dp"android:layout_height="48dp"android:paddingLeft="10dp"android:scaleType="centerInside"android:src="@drawable/video_back" /><Viewandroid:layout_weight="1"android:layout_width="0dp"android:layout_height="match_parent"/><ImageViewandroid:id="@+id/fullscreen"style="@style/left_icon_style"android:src="@drawable/full" /></LinearLayout><ProgressBarandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:id="@+id/loading"android:layout_centerInParent="true"/><ImageViewandroid:visibility="gone"android:layout_width="50dp"android:layout_height="50dp"android:layout_centerInParent="true"android:padding="5dp"android:id="@+id/start"/></RelativeLayout>api/*** 设置播放URL** @param url 播放url* @param cacheWithPlay 是否边播边缓存* @param title title* @return*/video.setUp("url", false, "");//设置播放路径video.startPlayLogic();//开始播放到此这篇关于Android GSYVideoPlayer视频播放器功能的实现的⽂章就介绍到这了,更多相关Android GSYVideoPlayer视频播放器内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!。

ANDROID课程设计视频播放器

ANDROID课程设计视频播放器

收获:了解了视 频播放器的设计 原理和实现方法, 提高了解决问题 的能力
不足:在课程设 计中遇到了一些 困难,如视频解 码、网络传输等 问题
不足:对 Android课程设 计的深入理解和 应用还有待提高, 需要进一步学习 和实践
技术更新:关注 Android最新技术动 态,及时更新课程 内容
实践教学:增加实 践教学环节,提高 学生动手能力
搜索功能:可以搜索和 播放特定视频
开发环境:Android Studio 编程语言:Java或Kotlin 开发工具:Android SDK、Gradle、Git等 测试工具:Android Emulator、Genymotion等 版本控制:GitHub、GitLab等 协作工具:Trello、Jira等
全屏/退出全屏:点击全屏 按钮进入/退出全屏模式
视频列表:显示视频列表, 点击可播放相应视频
设置按钮:点击进入设置 界面,调整视频播放相关 设置
视频播放器功能实 现
视频解码: 将视频文 件转换为 可播放的 格式
播放控制: 包括播放、 暂停、快 进、快退 等功能
视频渲染: 将解码后 的视频数 据渲染到 屏幕上
进度条:拖动进 度条可以跳转到 任意位置播放
音频解码:支持多种音频格式的解码,如MP3、AAC、WAV等 音频播放:支持音频文件的播放,包括单曲循环、列表循环、随机播放等模式 音频控制:支持音量调节、播放进度控制、暂停/继续播放等功能 音频效果:支持音效调节,如均衡器、环绕声、低音增强等效果
视频播放器界面设 计
顶部导航栏:包括返回、菜单、搜索等 按钮
中间视频播放区域:显示视频画面,可 调整播放进度、音量等
底部控制栏:包括播放/暂停、快进/快 退、全屏等按钮

Android视频播放器

Android视频播放器

Android视频播放器本人自项目中亲自测试过,保证可运行。

一个注释非常详细的Android视频播放器。

播放器有暂停按钮,返回按钮,进度条等。

播放的视频链接来自网络,怎么修改成本地视频播放,请各位大虾周知周知周知!方便的请私信我。

大家共同研究探讨。

项目组织结构如图所示:layout布局文件main.xml<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="/apk/res/android"android:layout_width="fill_parent"android:layout_height="fill_parent"><SurfaceViewandroid:id="@+id/mSurfaceView"android:layout_width="wrap_content"android:layout_height="wrap_content" ></SurfaceView><ProgressBarandroid:id="@+id/pb"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"/><Buttonandroid:layout_marginBottom="14dp"android:layout_gravity="bottom|center"android:id="@+id/play"android:layout_width="85dp"android:layout_height="35dp"android:background="@drawable/movie_stop_bt"/><RelativeLayoutandroid:background="#00000000"android:focusable="true"android:gravity="top"android:layout_gravity="top"android:id="@+id/rl2"android:layout_width="fill_parent"android:layout_height="55dp" ><Buttonandroid:layout_centerVertical="true"android:textSize="10sp"android:paddingLeft="5dp"android:textColor="#ffffff"android:layout_marginLeft="5dp"android:text="返回"android:id="@+id/back"android:layout_alignParentLeft="true"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@drawable/back_bt_seletor" /><SeekBarandroid:layout_marginLeft="5dp"android:layout_marginRight="5dp"android:layout_toRightOf="@+id/back"android:id="@+id/seekbar"style="?android:attr/progressBarStyleHorizontal"android:layout_width="fill_parent"android:layout_height="12dp"android:layout_centerVertical="true"android:background="@drawable/seek_bar"android:thumb="@drawable/seek_bar_seletor"/></RelativeLayout></FrameLayout>menu文件夹main.xml<menu xmlns:android="/apk/res/android" ><itemandroid:id="@+id/menu_settings"android:orderInCategory="100"android:title="@string/menu_settings"/></menu>string定义字符文件夹strings.xml<?xml version="1.0" encoding="utf-8"?><resources><string name="app_name">MyMoviePlay</string><string name="hello_world">Hello world!</string><string name="menu_settings">Settings</string></resources>styles.xml<resources><!--Base application theme, dependent on API level. This theme is replaced by AppBaseTheme from res/values-vXX/styles.xml on newer devices.--><style name="AppBaseTheme" parent="android:Theme.Light"><!--Theme customizations available in newer API levels can go inres/values-vXX/styles.xml, while customizations related tobackward-compatibility can go here.--></style><!-- Application theme. --><style name="AppTheme" parent="AppBaseTheme"><!-- All customizations that are NOT specific to a particular API-level can go here. --></style></resources>drawable文件夹back_bt_seletor.xml<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="/apk/res/android" ><item android:state_pressed="true" android:drawable="@drawable/iphone_back_button_1"></item><item android:drawable="@drawable/iphone_back_button_0"></item></selector>seek_bar.xml<?xml version="1.0" encoding="UTF-8"?><layer-list xmlns:android="/apk/res/android"><item android:id="@android:id/background"><shape><corners android:radius="10dip" /><gradient android:startColor="#ffffffff"android:centerColor="#ff000000" android:endColor="#ff808A87" android:centerY="0.45" android:angle="270" /></shape></item><item android:id="@android:id/progress"><clip><shape><corners android:radius="10dip" /><gradient android:startColor="#ffffffff"android:centerColor="#FF6347" android:endColor="#FF0000" android:centerY="0.45" android:angle="270" /></shape></clip></item></layer-list>seek_bar_seletor.xml<?xml version="1.0" encoding="UTF-8"?><selector xmlns:android="/apk/res/android"><!-- 按下状态--><itemandroid:state_pressed="true"android:drawable="@drawable/latest_video_play"/><!-- 普通无焦点状态--><itemandroid:state_focused="false"android:state_pressed="false"android:drawable="@drawable/latest_video_play"/></selector>项目图片AndroidManifest.xml<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="/apk/res/android"package="com.mymovieplay"android:versionCode="1"android:versionName="1.0" ><uses-sdkandroid:minSdkVersion="8"android:targetSdkVersion="12" /><applicationandroid:allowBackup="true"android:icon="@drawable/ic_launcher"android:label="@string/app_name"android:theme="@style/AppTheme" ><activityandroid:name="com.mymovieplay.MainActivity"android:label="@string/app_name" ><intent-filter><action android:name="android.intent.action.MAIN"android:configChanges="keyboardHidden|orientation"></action><category android:name="UNCHER" /> </intent-filter></activity></application><uses-permission android:name="android.permission.INTERNET" /></manifest>Class文件(Java文件)MainActivity.javapackage com.mymovieplay;//Download by import android.app.Activity;import android.media.MediaPlayer;import android.media.MediaPlayer.OnPreparedListener;import android.os.Bundle;import android.os.Handler;import android.os.Message;import youtParams;import android.util.Log;import android.view.SurfaceHolder;import android.view.SurfaceHolder.Callback;import android.view.SurfaceView;import android.view.View;import android.view.View.OnClickListener;import android.view.ViewGroup;import android.view.WindowManager;import android.widget.Button;import android.widget.RelativeLayout;import android.widget.SeekBar;import android.widget.Toast;public class MainActivity extends Activity {private Button bt; //用于开始和暂停的按钮private SurfaceView pView; //绘图容器对象,用于把视频显示在屏幕上private String url; //视频播放地址private MediaPlayer mediaPlayer; //播放器控件private int postSize; //保存义播视频大小private SeekBar seekbar; //进度条控件private boolean flag = true; //用于判断视频是否在播放中private RelativeLayout rl;private boolean display; //用于是否显示其他按钮private Button backButton; //返回按钮private View view; //ProgressBarprivate upDateSeekBar update; //更新进度条用@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);getWindow().setFlags(youtParams.FLAG_FULLSCREEN,youtParams.FLAG_FULLSCREEN); //全屏getWindow().addFlags(youtParams.FLAG_KEEP_SCREEN_ON);// 应用运行时,保持屏幕高亮,不锁屏init(); //初始化数据url = ":8751/Android/Test/Media/3gp/test.3gp"; //视频播放地址setListener(); //绑定相关事件}private void init() {mediaPlayer = new MediaPlayer(); //创建一个播放器对象update = new upDateSeekBar(); //创建更新进度条对象setContentView(yout.main); //加载布局文件backButton = (Button) findViewById(R.id.back); //返回按钮seekbar = (SeekBar) findViewById(R.id.seekbar); //进度条bt = (Button) findViewById(R.id.play);bt.setEnabled(false); //刚进来,设置其不可点击pView = (SurfaceView) findViewById(R.id.mSurfaceView);pView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//不缓冲pView.getHolder().setKeepScreenOn(true); //保持屏幕高亮pView.getHolder().addCallback(new surFaceView()); //设置监听事件rl = (RelativeLayout) findViewById(R.id.rl2);view = findViewById(R.id.pb);}class PlayMovie extends Thread { //播放视频的线程int post = 0;public PlayMovie(int post) {this.post = post;}@Overridepublic void run() {Message message = Message.obtain();try {Log.i("hck", "runrun "+url);mediaPlayer.reset(); //回复播放器默认mediaPlayer.setDataSource(url); //设置播放路径mediaPlayer.setDisplay(pView.getHolder()); //把视频显示在SurfaceView上mediaPlayer.setOnPreparedListener(new Ok(post)); //设置监听事件mediaPlayer.prepare(); //准备播放} catch (Exception e) {message.what = 2;Log.e("hck", e.toString());}super.run();}}class Ok implements OnPreparedListener {int postSize;public Ok(int postSize) {this.postSize = postSize;}@Overridepublic void onPrepared(MediaPlayer mp) {Log.i("hck", "play");Log.i("hck", "post " + postSize);view.setVisibility(View.GONE); //准备完成后,隐藏控件bt.setVisibility(View.GONE);rl.setVisibility(View.GONE);bt.setEnabled(true);display = false;if (mediaPlayer != null) {mediaPlayer.start(); //开始播放视频} else {return;}if (postSize > 0) { //说明中途停止过(activity调用过pase方法,不是用户点击停止按钮),跳到停止时候位置开始播放Log.i("hck", "seekTo ");mediaPlayer.seekTo(postSize); //跳到postSize大小位置处进行播放}new Thread(update).start(); //启动线程,更新进度条}}private class surFaceView implements Callback { //上面绑定的监听的事件@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}@Overridepublic void surfaceCreated(SurfaceHolder holder) { //创建完成后调用if (postSize > 0 && url!= null) { //说明,停止过activity调用过pase 方法,跳到停止位置播放new PlayMovie(postSize).start();flag = true;int sMax = seekbar.getMax();int mMax = mediaPlayer.getDuration();seekbar.setProgress(postSize * sMax / mMax);postSize = 0;view.setVisibility(View.GONE);}else {new PlayMovie(0).start(); //表明是第一次开始播放}}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) { //activity调用过pase 方法,保存当前播放位置if (mediaPlayer != null && mediaPlayer.isPlaying()) {postSize = mediaPlayer.getCurrentPosition();mediaPlayer.stop();flag = false;view.setVisibility(View.VISIBLE);}}}private void setListener() {mediaPlayer.setOnBufferingUpdateListener(newMediaPlayer.OnBufferingUpdateListener() {@Overridepublic void onBufferingUpdate(MediaPlayer mp, int percent) {}});mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { //视频播放完成@Overridepublic void onCompletion(MediaPlayer mp) {flag = false;bt.setBackgroundResource(R.drawable.movie_play_bt);}});mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Overridepublic void onPrepared(MediaPlayer mp) {}});/*** 如果视频在播放,则调用mediaPlayer.pause();,停止播放视频,反之,mediaPlayer.start() ,同时换按钮背景*/bt.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {if (mediaPlayer.isPlaying()) {bt.setBackgroundResource(R.drawable.movie_play_bt);mediaPlayer.pause();postSize = mediaPlayer.getCurrentPosition();} else {if (flag == false) {flag = true;new Thread(update).start();}mediaPlayer.start();bt.setBackgroundResource(R.drawable.movie_stop_bt);}}});seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {int value = seekbar.getProgress() * mediaPlayer.getDuration() //计算进度条需要前进的位置数据大小/ seekbar.getMax();mediaPlayer.seekTo(value);}@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {}@Overridepublic void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {}});/*** 点击屏幕,切换控件的显示,显示则应藏,隐藏,则显示*/pView.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {if (display) {bt.setVisibility(View.GONE);rl.setVisibility(View.GONE);display = false;} else {rl.setVisibility(View.VISIBLE);bt.setVisibility(View.VISIBLE);pView.setVisibility(View.VISIBLE);/*** 设置播放为全屏*/youtParams lp = pView.getLayoutParams();lp.height = LayoutParams.FILL_PARENT;lp.width = LayoutParams.FILL_PARENT;pView.setLayoutParams(lp);display = true;}}});backButton.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {if (mediaPlayer.isPlaying()) {mediaPlayer.stop();mediaPlayer.release();}mediaPlayer = null;MainActivity.this.finish();}});}/*** 更新进度条*/Handler mHandler = new Handler() {public void handleMessage(Message msg) {if (mediaPlayer == null) {flag = false;} else if (mediaPlayer.isPlaying()) {flag = true;int position = mediaPlayer.getCurrentPosition();int mMax = mediaPlayer.getDuration();int sMax = seekbar.getMax();seekbar.setProgress(position * sMax / mMax);} else {return;}};};class upDateSeekBar implements Runnable {@Overridepublic void run() {mHandler.sendMessage(Message.obtain());if (flag) {mHandler.postDelayed(update, 1000);}}}@Overrideprotected void onDestroy() { //activity销毁后,释放资源super.onDestroy();if (mediaPlayer != null) {mediaPlayer.stop();mediaPlayer.release();mediaPlayer = null;}System.gc();}}。

安卓课程设计 视频播放器

安卓课程设计 视频播放器

武汉工商学院信息工程学院项目名称:Android视频播放器学生姓名:学号:班级: 12通信本1班指导教师:2015年6月23日目录1 软件产品介绍 (1)1.1 软件产品名称 (1)1.2 软件总体功能 (1)2 软件开发环境 (1)2.1 Android平台 (1)2.2 JDK安装 (1)2.3 Android SDK安装以及系统设置 (3)2.4 Eclipse安装以及ADT工具的安装 (3)3 软件布局 (4)3.1 视频界面 (4)3.2 视频文件搜索功能 (5)3.3 播放控制功能 (5)3.4 其他功能 (6)4 程序流程图 (7)5 软件界面及程序主要代码 (8)5.1 软件在虚拟机上调试及分析 (8)5.2 软件在手机上的调试及分析 (8)5.3 程序主要代码 (9)6 设计总结及收获 (11)参考文献 (12)附录 (13)1 软件产品介绍1.1 软件产品名称一个基于Android平台的视频播放器1.2 软件总体功能(1) 能够播放.avi, .mp4等文件(2) 能处理简单的异常,例如文件不存在等(3) 能正常启动,退出(4) 能够在手机上使用该系统2 软件开发环境2.1 Android平台1.谷歌与开放手机联盟合作开发了Android, 这个联盟由包括中国移动、摩托罗拉、高通、宏达和T-Mobile在内的30多家技术和无线应用的领军企业组成。

2.Android是一个真正意义上的开放性移动设备综合平台。

通过与运营商、设备制造商、开发商和其他有关各方结成深层次的合作伙伴关系,来建立标准化、开放式的移动电话软件平台,在移动产业内形成一个开放式的生态系统,这样应用之间的通用性和互联性将在最大程度上得到保持。

3.所有的Android应用之间是完全平等的。

4.所有的应用都运行在一个核心的引擎上面,这个核心引擎其实就是一个虚拟机,它提供了一系列用于应用和硬件资源间进行通讯的API。

撇开这个核心引擎,Android的所有其他的东西都是“应用”。

Android视频播放器代码

Android视频播放器代码

Java代码部分:import java.io.IOException;import java.util.Random;import android.app.Activity;import android.content.Context;import NotFoundException;import android.media.AudioManager;import android.media.MediaPlayer;import android.media.MediaPlayer.OnBufferingUpdateListener;import android.media.MediaPlayer.OnCompletionListener;import android.os.Bundle;import android.os.Handler;import android.view.GestureDetector.OnGestureListener;import android.view.Gravity;import android.view.MotionEvent;import android.view.SurfaceHolder;import android.view.SurfaceView;import android.view.View;import android.view.Window;import android.view.WindowManager;import android.view.View.OnClickListener;import android.view.View.OnTouchListener;import android.widget.ImageButton;import android.widget.LinearLayout;import youtParams;import android.widget.PopupWindow;import android.widget.SeekBar;import android.widget.SeekBar.OnSeekBarChangeListener;import android.widget.TextView;import android.widget.Toast;public class PlayVideo extends Activity implementsOnGestureListener,OnClickListener,// 监听OnBufferingUpdateListener,// 当网络缓冲数据流变化的时候唤起的播放事件OnCompletionListener,// 当媒体资源在播放的时候到达终点时唤起的播放事件MediaPlayer.OnPreparedListener,SurfaceHolder.Callback// 回调函数{// 视频高和宽int videoWidth;int videoHeight;// 按钮ImageButton play;//定义快进按钮ImageButton fastPlay;//定义快退按钮ImageButton fastBack;// 控制栏LinearLayout layout_control; LinearLayout layout_prograss; LinearLayout videoBack;// 用来播放媒体MediaPlayer mediaPlayer; // 显示媒体SurfaceView surView;// 用来控制SurfaceView SurfaceHolder surHolder;// 路径String path;// 是否是播放状态boolean boTing = true;//获取播放的位置int num;//点击屏幕次数int count;//第一次点击int firClick;//第二次点击int secClick;//通过flag判断是否全屏boolean flag;//播放进度条SeekBar seekbar;//显示时间组建TextView showTime;//播放文件的时间int minute;int second;//进度条进度int progress;//线程控制MyThread mt;//声音控制SeekBar sound;//声音进度int soundId;//显示音量TextView showSound;//接取拖动进度条int videoLength;boolean f = true;//播放尺寸//按钮隐藏时间int hint = 5000;//用于接取点击ListView位置int position;//声称随机数Random random;//通过buttonFlag判断按钮背景boolean buttonFlag = true;//显示视频总时间TextView allTime;TextView distant;PopupWindow popuWindow;View view;boolean popFlag ;public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);this.getWindow().setFlags(youtParams.FLAG_FULLSCREEN, youtParams.FLAG_FULLSCREEN);setContentView(yout.video);// 产生对象view = this.getLayoutInflater().inflate(yout.popuwindow, null);//得到布局的IDvideoBack = (LinearLayout)view.findViewById(R.id.videoback);// 产生对象play = (ImageButton) view.findViewById(R.id.video_bu_bofang);layout_control = (LinearLayout)findViewById(yout_control);layout_prograss= (LinearLayout)findViewById(yout_prograss);seekbar = (SeekBar)view.findViewById(R.id.seekbar);showTime = (TextView)view.findViewById(R.id.showtime);fastPlay = (ImageButton)view.findViewById(R.id.fastplay);fastBack = (ImageButton)view.findViewById(R.id.fastback);sound = (SeekBar)view.findViewById(R.id.sound);showSound = (TextView)view.findViewById(R.id.showsound);surView = (SurfaceView) findViewById(R.id.surfaceview_1);allTime = (TextView)view.findViewById(R.id.alltime);distant = (TextView)findViewById(R.id.distant);surHolder = surView.getHolder();popuWindow = new PopupWindow(view, LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT);// 设置回调函数surHolder.addCallback(this);// 设置风格surHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//bu_boFang.setVisibility(View.INVISIBLE);// 设置按键监听play.setOnClickListener(this);//快进监听fastPlay.setOnClickListener(this);//快退按钮监听fastBack.setOnClickListener(this);//new随机数对象random = new Random();//接取到播放列表中点击的位置position = VideoList.position;try {//获取ShareActivity上下文VideoList.context = createPackageContext(".iotek", Context.CONTEXT_IGNORE_SECURITY);VideoList.share = VideoList.context.getSharedPreferences("setupadapter", VideoList.context.MODE_WORLD_READABLE);VideoList.editor = VideoList.share.edit();} catch (NameNotFoundException e) {e.printStackTrace();}//对读取的信息进行判断if (VideoList.share.getString("hinttime", "5秒").equals("5秒")) {hint = 5000;}if (VideoList.share.getString("hinttime", "5秒").equals("10秒")) {hint = 10000;}if (VideoList.share.getString("hinttime", "5秒").equals("15秒")) {hint = 15000;}//设置全屏播放surView.setOnTouchListener(new OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {// TODO Auto-generated method stub// handler.sendEmptyMessageAtTime(0x11, 3000);if(MotionEvent.ACTION_DOWN == event.getAction()){count++;if(count == 1){new countClear().start();firClick = (int) System.currentTimeMillis();if (!popFlag) {// // // popuWindow = new PopupWindow(view, LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT);popuWindow.showAtLocation(view, Gravity.BOTTOM, 0, 0);popFlag = true;handler.removeMessages(0x11);handler.sendEmptyMessageDelayed(0x11, hint);}//设置layout显示// if (!flag) {/* layout_control.setVisibility(View.VISIBLE);layout_prograss.setVisibility(View.VISIBLE);*///点击surfaceView延时3S发送信息/* handler.removeMessages(0x11);handler.sendEmptyMessageDelayed(0x11, hint);*/// }} else if (count == 2){secClick = (int) System.currentTimeMillis();if(secClick - firClick < 1000){flag = !flag;count = 0;}if(flag){distant.setHeight(0);surView.setLayoutParams(newyoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));surHolder.setFixedSize(480, 760);if (!popFlag) {// popuWindow = new PopupWindow(view, LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT);popuWindow.showAtLocation(view, Gravity.BOTTOM, 0, 0);popFlag = true;handler.removeMessages(0x11);handler.sendEmptyMessageDelayed(0x11, hint);}// 开始播放// mePlayer.start();}else{if (VideoList.share.getString("size", "4:3").equals("4:3")) {surView.setLayoutParams(newyoutParams(LayoutParams.MATCH_PARENT, 360));surHolder.setFixedSize(480, 360);distant.setHeight(250);if (!popFlag) {// popuWindow = new PopupWindow(view, LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT);popuWindow.showAtLocation(view,Gravity.BOTTOM, 0, 0);popFlag = true;handler.removeMessages(0x11);handler.sendEmptyMessageDelayed(0x11, hint);}}if (VideoList.share.getString("size", "4:3").equals("16:9")) {surView.setLayoutParams(newyoutParams(LayoutParams.MATCH_PARENT, 270));surHolder.setFixedSize(480, 270);distant.setHeight(250);if (!popFlag) {// popuWindow = new PopupWindow(view, LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT);popuWindow.showAtLocation(view,Gravity.BOTTOM, 0, 0);popFlag = true;handler.removeMessages(0x11);handler.sendEmptyMessageDelayed(0x11, hint);}}}count = 0;firClick = 0;secClick = 0;}}return true;}});//监听进度条进度seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {videoLength = seekBar.getProgress();// int q = mediaPlayer.getCurrentPosition();mediaPlayer.seekTo(videoLength);//获取进度条当前的位置// int dest = seekBar.getProgress();//设置播放器当期的播放位置// mediaPlayer.seekTo(num);}@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {}@Overridepublic void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {//得到seekbar的进度/* seekbar.setProgress(progress);videoLength = seekBar.getProgress();*/}});sound.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { @Overridepublic void onStopTrackingTouch(SeekBar seekBar) {// TODO Auto-generated method stubint i= seekBar.getProgress();mediaPlayer.setVolume(i/100f,i/100f);}@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {// TODO Auto-generated method stub}@Overridepublic void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {// TODO Auto-generated method stubint i= sound.getProgress();showSound.setText("音量:"+i);handler.removeMessages(0x11);handler.sendEmptyMessageDelayed(0x11, hint);}});}private void playVideo(){// 构建MediaPlayer对象mediaPlayer = new MediaPlayer();try {// 设置媒体文件路径mediaPlayer.setDataSource(VideoList.path);// 设置通过SurfaceView来显示画面mediaPlayer.setDisplay(surHolder);// 准备mediaPlayer.prepare();distant.setHeight(200);// 设置事件监听mediaPlayer.setOnBufferingUpdateListener(this);mediaPlayer.setOnCompletionListener(this);mediaPlayer.setOnPreparedListener(this);mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);seekbar.setMax(mediaPlayer.getDuration());//设置当前播放音量最大soundId = sound.getProgress();mediaPlayer.setVolume(soundId, soundId);showSound.setText("音量:"+soundId);mt = new MyThread();mt.start();handler.sendEmptyMessage(0x13);int n = mediaPlayer.getDuration();//获得持续时间seekbar.setMax(n);n = n/1000;int m = n/60;int h = m/60;int s = n%60;m = m%60;allTime.setText(String.format("影片长度:"+"%02d:%02d:%02d", h,m,s));} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalStateException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}// MediaPlayer.OnPreparedListenerpublic void onCompletion(MediaPlayer mp) {handler.sendEmptyMessage(0x14);}// MediaPlayer.OnPreparedListener// 这时能确保player处于Prepared状态,触发start是最合适的public void onPrepared(MediaPlayer mp) {if (VideoList.share.getString("size", "4:3").equals("4:3")) {surView.setLayoutParams(newyoutParams(LayoutParams.MATCH_PARENT, 360));// 设置播放视频的宽度和高度surHolder.setFixedSize(480, 360);// 开始播放mediaPlayer.start();}if (VideoList.share.getString("size", "4:3").equals("16:9")) {// 设置播放视频的宽度和高度surView.setLayoutParams(newyoutParams(LayoutParams.MATCH_PARENT, 270));surHolder.setFixedSize(480, 270);// 开始播放mediaPlayer.start();}}public void surfaceCreated(SurfaceHolder holder) {playVideo();}public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {}protected void onDestroy(){super.onDestroy();if (mediaPlayer != null){mediaPlayer.release();mediaPlayer = null;//关闭cursor// VideoList.cursor.close();//关闭数据库// VideoList.db.close();//改变线程循环条件f = false;handler.removeMessages(0x11);popuWindow.dismiss();}}public void onClick(View v) {if(v==play){//如果正在播放if (buttonFlag) {play.setImageResource(R.drawable.pause_1);mediaPlayer.pause();buttonFlag = false;}else{play.setImageResource(R.drawable.play_1);mediaPlayer.start();buttonFlag = true;}handler.removeMessages(0x11);handler.sendEmptyMessageDelayed(0x11, hint);}if (v == fastPlay) {int i = mediaPlayer.getCurrentPosition()+5000;mediaPlayer.seekTo(i);seekbar.setProgress(i);handler.removeMessages(0x11);handler.sendEmptyMessageDelayed(0x11, hint);}if (v == fastBack) {int i = mediaPlayer.getCurrentPosition()-5000;mediaPlayer.seekTo(i);seekbar.setProgress(i);handler.removeMessages(0x11);handler.sendEmptyMessageDelayed(0x11, hint);}}Handler handler = new Handler(){public void handleMessage(android.os.Message msg) {if (msg.what == 0x11) {if(popuWindow.isShowing()&&f){popuWindow.dismiss();popFlag = false;}////启动后设置layout隐藏/* layout_control.setVisibility(View.INVISIBLE);layout_prograss.setVisibility(View.INVISIBLE);*/}if (msg.what == 0x12) {if(mediaPlayer!=null){num = mediaPlayer.getCurrentPosition();}seekbar.setProgress(num);// 为时分秒赋值num = num/1000;int minute = num/60;int hour = minute/60;int second = num%60;minute = minute%60;/* if (mediaPlayer!=null) {seekbar.setProgress(mediaPlayer.getCurrentPosition());}*/showTime.setText(String.format("播放进度:"+"%02d:%02d:%02d", hour,minute,second));// handler.sendEmptyMessage(0x12);}if (msg.what == 0x14) {if (VideoList.share.getString("playstyle","顺序播放").equals("单曲循环")) {//释放播放的视频mediaPlayer.release();//游标移动到点击ListView位置// VideoList.cursor.moveToPosition(VideoList.position);//在数据库中取出ListView点击的路径VideoList.path = VideoList.cursor.getString(1);//播放视频playVideo();}if (VideoList.share.getString("playstyle", "顺序播放").equals("顺序播放")) { //释放当前的MediaPlayermediaPlayer.release();//自加position ++;if (position==VideoList.videoList.getCount()) {position = 0;}//游标向下移动VideoList.cursor.moveToPosition(position);//取出移动后的视频路径VideoList.path = VideoList.cursor.getString(1);//播放视频playVideo();}if (VideoList.share.getString("playstyle", "顺序播放").equals("随机播放")) { //释放播放的视频mediaPlayer.release();int r = random.nextInt(VideoList.videoList.getCount()-1);VideoList.cursor.moveToPosition(r);//在数据库中取出ListView点击的路径VideoList.path = VideoList.cursor.getString(1);//播放视频playVideo();}}};};class MyThread extends Thread{@Overridepublic void run() {handler.sendEmptyMessageDelayed(0x11, hint);// if (mePlayer.getDuration()+"".equals("0") ) {while (f) {try {sleep(1000);handler.sendEmptyMessage(0x12);}catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}// }}}class countClear extends Thread{@Overridepublic void run() {try {sleep(1000);//睡一秒后count清0count = 0;} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) { // TODO Auto-generated method stub}@Overridepublic void onBufferingUpdate(MediaPlayer mp, int percent) { // TODO Auto-generated method stub}@Overridepublic boolean onDown(MotionEvent e) {// TODO Auto-generated method stubreturn false;}@Overridepublic boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {// TODO Auto-generated method stubreturn false;}@Overridepublic void onLongPress(MotionEvent e) {// TODO Auto-generated method stub}@Overridepublic boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {// TODO Auto-generated method stubreturn false;}@Overridepublic void onShowPress(MotionEvent e) {// TODO Auto-generated method stub}@Overridepublic boolean onSingleTapUp(MotionEvent e) {// TODO Auto-generated method stubreturn false;}}配置文件:Video.xml文件<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="/apk/res/android"android:id="@+id/videoback"android:layout_width="fill_parent"android:layout_height="fill_parent"android:orientation="vertical" ><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:background="#00000000"android:id="@+id/distant"/><SurfaceViewandroid:id="@+id/surfaceview_1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="300px"android:layout_gravity="center_horizontal" /></LinearLayout>Popuwindow.xml配置文件<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="/apk/res/android"android:id="@+id/videoback"android:layout_width="fill_parent"android:layout_height="fill_parent"android:orientation="vertical" ><LinearLayoutandroid:id="@+id/layout_prograss"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_gravity="bottom"android:orientation="vertical" ><SeekBarandroid:id="@+id/seekbar"android:layout_width="match_parent"android:layout_height="8px"android:progressDrawable="@drawable/seekbar"android:thumb="@drawable/seekbutton"android:progress="0" /><TextViewandroid:id="@+id/showtime"android:layout_width="match_parent"android:layout_height="wrap_content"/><TextViewandroid:id="@+id/alltime"android:layout_width="match_parent"android:layout_height="wrap_content"/><SeekBarandroid:id="@+id/sound"android:layout_height="8px"android:progressDrawable="@drawable/seekbar"android:thumb="@drawable/seekbutton"android:progress="50" /><TextViewandroid:id="@+id/showsound"android:layout_width="match_parent"android:layout_height="wrap_content"/></LinearLayout><LinearLayoutandroid:id="@+id/layout_control"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_gravity="bottom"android:orientation="horizontal" ><ImageButtonandroid:id="@+id/fastback"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_weight="1"android:background="#00000000"android:scaleType="fitCenter"android:src="@drawable/stepback" /><ImageButtonandroid:id="@+id/video_bu_bofang"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_weight="1"android:background="#00000000"android:scaleType="fitCenter"android:src="@drawable/play_1" /><ImageButtonandroid:id="@+id/fastplay"android:layout_width="wrap_content"android:layout_weight="1"android:background="#00000000"android:scaleType="fitCenter"android:src="@drawable/stepfor" /> </LinearLayout></LinearLayout>。

Android使用FFmpeg--ffmpeg实现视频播放

Android使用FFmpeg--ffmpeg实现视频播放

Android使用FFmpeg--ffmpeg实现视频播放关于前言如果你已经准备好ffmpeg的开发环境,那么我们在这篇文章中实现对视频的一个播放,如果还没有准备好,请看前面的内容。

正文视频播放大概流程图.pngOk,上图就是使用ffmpeg实现了一个视频的播放的大概流程图,那么,我们将根据流程图来编写代码,这样子,代码的编写就会显得比较简单,比较好理解了。

1.注册各大组件,这一步很重要,如果不注册就无法使用后面的函数了。

av_register_all(;2.在解码之前我们得获取里面的内容吧,所以这一步就是打开地址并且获取里面的内容。

其中avFormatContext是内容的一个上下文,inputPath为输入的地址。

AVFormatContext *avFormatContext = avformat_alloc_context(;//获取上下文 avfor mat_open_input(&avFormatContext, inputPath, NULL, NULL)//解封装 avformat_fin d_stream_info(avFormatContext, NULL)3.我们在上面已经获取了内容,但是在一个音视频中包括了音频流,视频流和字幕流,所以在所有的内容当中,我们应当找出相对应的视频流。

int video_index=-1; for (int i = 0; i < avFormatContext->nb_streams; ++i) { if (a vFormatContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) { //如果是视频流,标记一哈 video_index = i; } }4.在第三步的时候已经找到了视频流,那么我们就对视频流进行解码、转换和绘制。

a.如果要进行解码,那么得有解码器并打开解码器。

Android实现视频播放--腾讯浏览服务(TBS)功能

Android实现视频播放--腾讯浏览服务(TBS)功能

Android实现视频播放--腾讯浏览服务(TBS)功能TBS视频播放TBS视频播放器可以⽀持市⾯上⼏乎所有的视频格式,包括mp4, flv, avi, 3gp, webm, ts, ogv, m3u8, asf, wmv, rm, rmvb, mov, mkv等18种视频格式。

同时⽀持硬件解码,使得内存占⽤,稳定性相较于系统播放器都更优。

接⼊TBS1.导⼊jar⽂件和so⽂件2.初始化Application⾃定义⼀个Application类,对X5内核进⾏初始化public class MyAppliction extends Application {@Overridepublic void onCreate() {super.onCreate();//回调接⼝初始化完成接⼝回调QbSdk.PreInitCallback pcb=new QbSdk.PreInitCallback() {@Overridepublic void onCoreInitFinished() {}@Overridepublic void onViewInitFinished(boolean b) {//x5內核初始化完成的回调,为true表⽰x5内核加载成功,否则表⽰x5内核加载失败,会⾃动切换到系统内核。

Log.e("myApplication", " x5内核加载成功?" + b);}};//x5内核预加载,异步初始化x5 webview所需环境QbSdk.initX5Environment(getApplicationContext(), pcb);}}在AndroidManifest.xml进⾏声明<application android:name="com.example.xch.tbsvideoplay.MyAppliction"3.使⽤直接在清单⽂件AndroidManifest.xml中配置SDK中的视频播放Activity<activityandroid:name="com.tencent.smtt.sdk.VideoActivity"android:alwaysRetainTaskState="true"android:configChanges="orientation|screenSize|keyboardHidden"android:exported="false"android:launchMode="singleTask"><intent-filter><action android:name="com.tencent.smtt.tbs.video.PLAY" /><category android:name="android.intent.category.DEFAULT" /></intent-filter></activity>在代码中直接调⽤TbsVideo.openVideo()播放/*** 直接调⽤播放视频* @param videoUrl 视频地址*/private void startPlay(String videoUrl){//判断当前是否可⽤if(TbsVideo.canUseTbsPlayer(getApplicationContext())){//播放视频TbsVideo.openVideo(getApplicationContext(), videoUrl);}}4.添加权限<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /><uses-permission android:name="android.permission.READ_PHONE_STATE" /><uses-permission android:name="android.permission.READ_SETTINGS" /><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /><!-- 硬件加速对X5视频播放有利,建议开启 --><uses-permission android:name="android.permission.GET_TASKS" />效果图优化先看⼀下优化之后的效果⾃定义TBS的WebView,充分发挥X5内核的作⽤1.⾃定义webview需继承TBS的webview,包⼀定不能导错:com.tencent.smtt.sdk.WebView public class X5WebView extends WebView {private WebViewClient client = new WebViewClient() {/*** 防⽌加载⽹页时调起系统浏览器*/public boolean shouldOverrideUrlLoading(WebView view, String url) {view.loadUrl(url);return true;}};@SuppressLint("SetJavaScriptEnabled")public X5WebView(Context arg0, AttributeSet arg1) {super(arg0, arg1);this.setWebViewClient(client);initWebViewSettings();this.getView().setClickable(true);}/*** 初始化webview设置*/private void initWebViewSettings() {WebSettings webSetting = this.getSettings();...}/*** 这⾥可以为⾃定义webview绘制背景或⽂字* @param canvas* @param child* @param drawingTime* @return*/@Overrideprotected boolean drawChild(Canvas canvas, View child, long drawingTime) {boolean ret = super.drawChild(canvas, child, drawingTime);canvas.save();...return ret;}public X5WebView(Context arg0) {super(arg0);setBackgroundColor(85621);}}2.布局中使⽤⾃定义WebView<com.example.xch.tbsvideoplay.tools.X5WebViewandroid:id="@+id/x5_webview"android:layout_width="match_parent"android:layout_height="200dp"android:scrollbars="none" />3.使⽤⾃定义WebView播放视频/*** 使⽤⾃定义webview播放视频* @param vedioUrl 视频地址*/private void startPlay(String vedioUrl) {x5webView.loadUrl(vedioUrl);getWindow().setFormat(PixelFormat.TRANSLUCENT);x5webView.getView().setOverScrollMode(View.OVER_SCROLL_ALWAYS);x5webView.setWebChromeClient(new WebChromeClient());}4.⽀持横竖屏切换在AndroidManifest.xml中给当前Activity配置configChanges属性<activityandroid:name="com.example.xch.tbsvideoplay.VideoPlayActivity"android:configChanges="orientation|screenSize|keyboardHidden"/>总结以上所述是⼩编给⼤家介绍的Android实现视频播放--腾讯浏览服务(TBS),希望对⼤家有所帮助,如果⼤家有任何疑问请给我留⾔,⼩编会及时回复⼤家的。

Android原生视频播放VideoView的使用

Android原生视频播放VideoView的使用

Android原⽣视频播放VideoView的使⽤本⽂实例为⼤家分享了Android原⽣视频播放VideoView的具体代码,供⼤家参考,具体内容如下布局⽂件activity_video.xml<RelativeLayout xmlns:android="/apk/res/android"xmlns:tools="/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><VideoViewandroid:id="@+id/videoView"android:layout_width="match_parent"android:layout_height="match_parent" /><ProgressBarandroid:id="@+id/progressBar"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true" /></RelativeLayout>对应的Avtivity:VideoActivity.javapackage com.example.administrator.main;import android.content.Intent;import android.media.MediaPlayer;import .Uri;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.DisplayMetrics;import android.view.MotionEvent;import android.view.View;import android.widget.MediaController;import android.widget.ProgressBar;import android.widget.RelativeLayout;import android.widget.VideoView;public class VideoActivity extends AppCompatActivity {private ProgressBar progressBar;private VideoView videoView;private MediaController mediaController;private int intPositionWhenPause = -1;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(yout.activity_video);//调⽤系统⾃带视频播放或者安装的第三⽅播放器// Uri uri=Uri.parse("/mda-ig4tp6gnqwu5we8i/mda-ig4tp6gnqwu5we8i.mp4");// Intent intent=new Intent(Intent.ACTION_VIEW);// intent.setDataAndType(uri,"video/*");// startActivity(intent);initVideoView();}/*** 初始化videoview播放*/public void initVideoView() {//初始化进度条progressBar = (ProgressBar) findViewById(R.id.progressBar);//初始化VideoViewvideoView = (VideoView) findViewById(R.id.videoView);//初始化videoview控制条mediaController = new MediaController(this);//设置videoview的控制条videoView.setMediaController(mediaController);//设置显⽰控制条mediaController.show(0);//设置播放完成以后监听videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {@Overridepublic void onCompletion(MediaPlayer mp) {}});//设置发⽣错误监听,如果不设置videoview会向⽤户提⽰发⽣错误videoView.setOnErrorListener(new MediaPlayer.OnErrorListener() {@Overridepublic boolean onError(MediaPlayer mp, int what, int extra) {return false;}});//设置在视频⽂件在加载完毕以后的回调函数videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {@Overridepublic void onPrepared(MediaPlayer mp) {progressBar.setVisibility(View.GONE);videoView.start();}});//设置videoView的点击监听videoView.setOnTouchListener(new View.OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {return false;}});//设置⽹络视频路径Uri uri = Uri.parse("/mda-ig4tp6gnqwu5we8i/mda-ig4tp6gnqwu5we8i.mp4");videoView.setVideoURI(uri);//设置为全屏模式播放setVideoViewLayoutParams(2);}/*** 设置videiview的全屏和窗⼝模式** @param paramsType 标识 1为全屏模式 2为窗⼝模式*/public void setVideoViewLayoutParams(int paramsType) {//全屏模式if (1 == paramsType) {//设置充满整个⽗布局youtParams LayoutParams = new youtParams(youtParams.MATCH_PARENT, youtParams.MATCH_PARENT); //设置相对于⽗布局四边对齐LayoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);LayoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);LayoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);LayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);//为VideoView添加属性videoView.setLayoutParams(LayoutParams);} else {//窗⼝模式//获取整个屏幕的宽⾼DisplayMetrics DisplayMetrics = new DisplayMetrics();this.getWindowManager().getDefaultDisplay().getMetrics(DisplayMetrics);//设置窗⼝模式距离边框50int videoHeight = DisplayMetrics.heightPixels;int videoWidth = DisplayMetrics.widthPixels;youtParams LayoutParams = new youtParams(videoWidth, videoHeight);//设置居中LayoutParams.addRule(RelativeLayout.ALIGN_TOP);//为VideoView添加属性videoView.setLayoutParams(LayoutParams);}}/*** 页⾯暂停效果处理*/@Overrideprotected void onPause() {super.onPause();//如果当前页⾯暂停则保存当前播放位置,全局变量保存intPositionWhenPause = videoView.getCurrentPosition();//停⽌回放视频⽂件videoView.stopPlayback();}/*** 页⾯从暂停中恢复*/@Overrideprotected void onResume() {super.onResume();//跳转到暂停时保存的位置if (intPositionWhenPause >= 0) {videoView.seekTo(intPositionWhenPause);//初始播放位置intPositionWhenPause = -1;}}}以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。

android视频播放器-源码

android视频播放器-源码

本文讲的是“android 视频播放器”,并附有播放器源代码1.开发环境:eclipse3.6ADT-0.9.7AVD1.62.程序运行效果A.启动AVD(虚拟设备)在应用程序界面主界面,我们可以看到“艾文播放器”B.点击打开后,会播放默认的一个coco的广告C.点击标题栏的按钮可以打开文件浏览器D.点击视频文件,会提示使用的播放器E.选择“艾文视频播放器”打开后,按ctrl+f12,切换到横屏,发现视频并没有中断,而是继续播放3.源码分析A.图片都是网上找的,还有就是自己收藏的地方翻出来的,不多讲了。

B.布局文件main.xml:期中包含一个videoview,用于播放视频图像titlebar.xml:主视图的标题栏布局,主要用于添加一个菜单按钮,点击后打开文件浏览器myfile.xml:为文件浏览器布局C.VideoPlay.javaview plaincopy to clipboardprint?1.package com.bestaone;2.3.import android.app.Activity;4.import android.content.Intent;5.import .Uri;6.import android.os.Bundle;7.import android.util.Log;8.import android.view.View;9.import android.view.View.OnClickListener;10.import android.view.Window;11.import android.view.WindowManager;12.import android.widget.ImageButton;13.import android.widget.MediaController;14.import android.widget.TextView;15.import android.widget.VideoView;16.17.public class VideoPlay extends Activity {18.19. private VideoView videoView;20. private static int index = 0;21.22.@Override23. public void onCreate(Bundle savedInstanceState) {24. super.onCreate(savedInstanceState);25. requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);26. setContentView(yout.main);27. getWindow().setFlags(youtParams.FLAG_FULLSCREEN, WindoyoutParams.FLAG_FULLSCREEN);//28. //设置标题栏的布局29. getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, yout.titlebar);30. //这个空间暂时没用31. final TextView titleTV = (TextView) findViewById(R.id.title);32. titleTV.setText("");33. ImageButton titleButton = (ImageButton) findViewById(R.id.titleButton);34. //为按钮添加鼠标点击事件35. titleButton.setOnClickListener(new OnClickListener() {36.@Override37. public void onClick(View v) {38. Intent intent = new Intent();39. intent.setClass(VideoPlay.this, MyFile.class);40. //打开MyFile activity41. startActivity(intent);42. }43. });44. Intent intent = getIntent();45. String value = intent.getDataString();46. videoView = (VideoView) findViewById(R.id.VideoView01);47. if(value==null){48. //加载默认视频49. videoView.setVideoURI(Uri.parse("android.resource://com.bestaone/" + R.drawable.coco));50. }else{51. //通过文件浏览器传过来的视频路径,播放52. videoView.setVideoPath(value);53. }54. videoView.setMediaController(new MediaController(VideoPlay.this));55. videoView.requestFocus();56. }57.58. //启动59.@Override60. protected void onStart() {61. super.onStart();62. Log.i("mp4", "@@@ on start");63. }64.65.@Override66. protected void onResume() {67. super.onResume();68. videoView.seekTo(index);69. videoView.start();70. Log.i("mp4", "@@@ on resume");71. }72.73. //暂停74.@Override75. protected void onPause() {76. super.onPause();77. Log.i("mp4", "@@@ on pause");78. }79.80. //停止81.@Override82. protected void onStop() {83. super.onStop();MyFile.javaview plaincopy to clipboardprint?1.package com.bestaone;2.3.import java.io.File;4.import java.util.ArrayList;5.import java.util.List;6.7.import android.app.ListActivity;8.import android.content.Intent;9.import .Uri;10.import android.os.Bundle;11.import android.view.KeyEvent;12.import android.view.View;13.import android.widget.AdapterView;14.import android.widget.AdapterView.OnItemLongClickListener;15.import android.widget.Button;16.import android.widget.EditText;17.import android.widget.ImageButton;18.import android.widget.ListView;19.import android.widget.TextView;20.import android.widget.Toast;21.22.public class MyFile extends ListActivity implements OnItemLongClickListener {23.24. //支持的视频格式25. private final String[][] FILE_MapTable = {26.27. // {后缀名, MIME类型}28. { ".3gp", "video/3gpp" },29. { ".mov", "video/quicktime" },30. { ".avi", "video/x-msvideo" },31. { ".rmvb", "audio/x-pn-realaudio" },32. { ".wmv", "audio/x-ms-wmv" }33.34. };35.36. private List<String> items = null; // items:存放显示的名称37. private List<String> paths = null; // paths:存放文件路径38. private List<String> sizes = null; // sizes:文件大小39. private String rootPath = "/"; // rootPath:起始文件夹40. private TextView path_edit;41. private ImageButton rb_qry;42. private int isZoom = 0;43. private int isOpen = 0;44.45.46. /**47. * 重写返回键功能:返回上一级文件夹48. */49.@Override50. public boolean onKeyDown(int keyCode, KeyEvent event) {51. // 是否触发按键为back键52. if (keyCode == KeyEvent.KEYCODE_BACK) {53. path_edit = (EditText) findViewById(R.id.path_edit);54. File file = new File(path_edit.getText().toString());55. if (rootPath.equals(path_edit.getText().toString())) {56. return super.onKeyDown(keyCode, event);57. } else {58. getFileDir(file.getParent());59. return true;60. }61. // 如果不是back键正常响应62. } else {63. return super.onKeyDown(keyCode, event);64. }65. }66.67.@Override68. protected void onCreate(Bundle icicle) {69. super.onCreate(icicle);70. setContentView(yout.myfile);71.72. path_edit = (EditText) findViewById(R.id.path_edit);73. rb_qry = (ImageButton) findViewById(R.id.qry_button);74. rb_qry.setOnClickListener(listener_qry);75. getListView().setOnItemLongClickListener(this);76. getFileDir(rootPath);77. }78.79. Button.OnClickListener listener_qry = new Button.OnClickListener() {80. public void onClick(View arg0) {81. File file = new File(path_edit.getText().toString());82. if (file.exists()) {83. if (file.isFile()) {84. openFile(file);85. } else {86. getFileDir(path_edit.getText().toString());87. }88. } else {89. Toast.makeText(MyFile.this, "找不到该位置,请确定位置是否正确!",Toast.LENGTH_SHORT).show();90. }91. }92. };93.94. /**95. * 设置ListItem被点击时要做的动作96. */97.@Override98. protected void onListItemClick(ListView l, View v, int position, long id) {99. File file = new File(paths.get(position));100. fileOrDirHandle(file);101. }102.103.104. /**105. * 处理文件或者目录的方法106. * @param file107. * @param flag108. */109. private void fileOrDirHandle(final File file) {110. if (file.isDirectory()) {111. getFileDir(file.getPath());112. } else {113. openFile(file);114. }115. }116.117. /**118. * 取得文件结构的方法119. * @param filePath120. */121. private void getFileDir(String filePath) {122. /* 设置目前所在路径 */123. path_edit.setText(filePath);124. items = new ArrayList<String>();125. paths = new ArrayList<String>();126. sizes = new ArrayList<String>();127. File f = new File(filePath);128. File[] files = f.listFiles();129. if (files != null) {130. /* 将所有文件添加ArrayList中 */131. for (int i = 0; i < files.length; i++) {132. if (files[i].isDirectory()) {133. items.add(files[i].getName());134. paths.add(files[i].getPath());135. sizes.add("");136. }137. }138.139. for (int i = 0; i < files.length; i++) {140. if (files[i].isFile()) {141. String fileName = files[i].getName();142. int index = stIndexOf(".");143. if(index>0){144. String endName = fileName.substring(index,fileName.length()).toLowe rCase();145. String type = null;146. for(int x=0; x<FILE_MapTable.length; x++){147. //支持的格式,才会在文件浏览器中显示148. if(endName.equals(FILE_MapTable[x][0])){149. type = FILE_MapTable[x][1];150. break;151. }152. }153. if(type!=null){154. items.add(files[i].getName());155. paths.add(files[i].getPath());156. sizes.add(MyUtil.fileSizeMsg(files[i]));157. }158. }159. }160. }161. }162. /* 使用自定义的MyAdapter来将数据传入ListActivity */163. setListAdapter(new FileListAdapter(this, items, paths, sizes, isZoom)); 164. }165.166.167. /**168. * 打开文件169. * @param f170. */171. private void openFile(File f) {172. Intent intent = new Intent();173. intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);174. intent.setAction(android.content.Intent.ACTION_VIEW);175. // 跳出列表供选择176. String type = "video/*";177. if (isOpen == 0) {178. type = MyUtil.getMIMEType(f, true);179. }180. // 设置intent的file与MimeType181. intent.setDataAndType(Uri.fromFile(f), type);182.// intent.putExtra("path", "sms_context");183. startActivity(intent);184. }185.186.@Override187. public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, 188. long arg3) {189. // TODO Auto-generated method stub190. return false;191. }192.193.}。

android编程调用mediaplayer播放器

android编程调用mediaplayer播放器

mediaplayer的生命周期.1. 当mediaplayer被new出来的时候处于idle状态.(空闲状态)mediaPlayer.reset()之前:可以设置错误的监听器.2. setDataSource() 设置数据源. 初始化完毕.3. prepare() 准备开始播放视频或者音频.HDprepareAsync() 异步准备.4. start() 开始播放介绍:这款播放器是基于FMpeg音视频解码库的Vitamio框架和系统的MediaPlayer结合的方式开发的,支持flv、rmvb、mkv、mov、avi、mp4等多种视频格式,mp3、ogg、wma、mid、m4a等多种音频格式,实现了网络视频和本地视频播放,网络音频和本地音频的播放等功能。

技术:软解码和硬解码的使用,json解析服务端数据,采用Popuwindow显示播放控制器播放流程:视频播放器(网络视频,本地视频),音频播放器(网络音频,本地音频)Andoid默认支持视频格式是:mp4,3gp,wmvAndoid默认支持音频格式是:mp3,ogg播放原则:先用系统播放器去播放,当系统播放器播放出错的时候,切换到Vitamio播放器;我已经知道系统播放器播放不了的,直接用Vitamio播放器(支持在线视频,可以从Youku,或酷六客户端调用我们的播放器进来播放)用到了getIntent().getData(); 这个负责得到Url,当然还有单独的播放方法根据这URL地址去播放,但别忘了要功能清单文件里注明<data android:mimeType="video/*" android:scheme="http"/>网络视频<data android:mimeType="video/*" android:scheme="file"/>本地视频<data android:mimeType="audio/*" android:scheme="http"/>网络音频<data android:mimeType="audio/*" android:scheme="file"/>本地音频界面:加载控制视频界面的是一个PopupWindow,作为一种用户提醒而且其开销也比activity 要小,实现了播放,暂停,上一个(后退),下一个(判断一下是否是文件列表,如果是就播放下一个视频否则就快进),声音控制(0-15),自定义一个类控制PopupWindow显示和隐藏的,设置6秒隐藏,用到了handlerMessage消息机制,做了一个方法,6s中之后发一个消息,调用隐藏控制面板的方法硬解码和软解码的大概原理:硬解码:所谓的硬解码就是用系统的接口实现的播放器,那么就可以叫做用硬解码。

android视频播放简单实现示例(VideoViewMediaPlayer)

android视频播放简单实现示例(VideoViewMediaPlayer)

android视频播放简单实现⽰例(VideoViewMediaPlayer)如果你看过我的《android⾳乐播放简单实现(MediaPlayer)》,那么本篇将会毫⽆压⼒。

⾸先是主界⾯的三个按钮和⼀个播放控件<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="/apk/res/android"xmlns:tools="/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context="com.cofox.myplayvideo.MainActivity"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Buttonandroid:id="@+id/btnPlay"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="Play"android:textAllCaps="false" /><Buttonandroid:id="@+id/btnPause"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="Pause"android:textAllCaps="false" /><Buttonandroid:id="@+id/btnReplay"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="Replay"android:textAllCaps="false" /></LinearLayout><VideoViewandroid:id="@+id/vdvwFilm"android:layout_width="match_parent"android:layout_height="wrap_content" /></LinearLayout>在 MainActivity.java 中这⾥需要⽤到的是 VideoView 作为视频播放时的显⽰位置。

android 播放视频代码

android 播放视频代码

android 播放视频播放视频的两种方式:使用VideoView播放视频(方便,推荐)使用MediaPlayer和SurfaceView播放视频(早期的方式)第一种方式:使用VideoView播放视频的步骤如下:在界面布局文件中定义VideoView组件,或在程序中创建VideoView组建调用VideoView的如下两个方法加载指定视频setVideoPath(String paht):加载path文件所代表的视频setVideoURI(URI uri):加载uri所对应的视频调用VideoVIew的start(),stop(),pause()方法来控制视频播放MediaContraller类与VideoView一起结合使用的还有一个MediaContraller类,它的作用时提供一个友好的图形控制界面,通过该控制界面来控制视频的播放,快进键,暂停键,后退键以及播放进度条都是该类提供例子代码:xml布局:?<!--?xml version="1.0"encoding="utf-8"?-->1<linearlayout2 3 4 5 xmlns:android="/apk/res/android "android:ori entation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"><!-- 定义VideoView 播放视频 --><videoviewandroid:id="@+id/video"android:layout_width="match_parent"android:lay out_height="match_parent"></videoview></linearlayout>Activity : ?1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 importjava.io.File;importandroid.app.Activity;importandroid.graphics.PixelFormat;importandroid.os.Bundle;importandroid.widget.MediaController;importandroid.widget.VideoView;publicclassVedioViewTestextendsActivity {VideoView videoView;MediaController mController;@OverridepublicvoidonCreate(Bundle savedInstanceState) {16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 super.onCreate(savedInstanceState);getWindow().setFormat(PixelFormat.TRANSLUCENT);setContentView(yout.main);// 获取界面上VideoView 组件videoView = (VideoView) findViewById(R.id.video);// 创建MediaController 对象mController =newMediaController(this);File video =newFile("/mnt/sdcard/movie.mp4");if(video.exists()) {videoView.setVideoPath(video.getAbsolutePath());//① // 设置videoView 与mController 建立关联videoView.setMediaController(mControl ler);//② // 设置mController 与videoView 建立关联mController.setMediaPlayer(videoView);//③// 让VideoView 获取焦点videoView.requestFocus();}}}第二种方式:使用MediaPlayer 播放视频的步骤如下:创建MediaPlayer 对象,并让它加载指定的视频文件在界面布局文件中定义SurfaceView 组件,或在程序中创建SurfaceView 组件,并为SurfaceView 的SurfaceView 的SurfaceHolder 增加Callback 监听器调用 MediaPlayer 对象的setPisplay(SurfaceHolder sh):将所播放的视频图像输出到指定的SurfaceView 组件调用MediaPlayer 对象的start(),stop(),和pause()方法来控制视频的播放例子代码:xml 布局: ?1234 56 78 9<!--?xml version="1.0"encoding="utf-8"?--><relativelayoutxmlns:android="/apk/res/android "android:ori entation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"><surfaceview android:id="@+id/surfaceView"android:layout_width="match_parent"andro id:layout_height="360dp"> <linearlayout android:orientation="horizontal"android:layout_width="match_parent"an droid:layout_height="wrap_content"android:layout_alignparentbottom="t rue"android:gravity="center_horizontal"><imagebuttonandroid:id="@+id/play"android:layout_width="wrap_content"android:layo ut_height="wrap_content"android:src="@drawable/play"><imagebuttonandroid:id="@+id/pause"android:layout_width="wrap_content"android:lay out_height="wrap_content"android:src="@drawable/pause"> <imagebuttonandroid:id="@+id/stop"android:layout_width="wrap_content"android:layo ut_height="wrap_content"android:src="@drawable/stop"></imagebutton></imagebutton></imagebutton></linearlayout></surfaceview></relativelayout>Activity :?1 2 3 4 5 6 7 8 910111213141516171819202122 importjava.io.IOException;importandroid.app.Activity;importandroid.media.AudioManager;importandroid.media.MediaPlayer;importandroid.os.Bundle;importandroid.util.DisplayMetrics; importandroid.view.SurfaceHolder;importandroid.view.SurfaceView;importandroid.view.View;importandroid.view.View.OnClickListener; importandroid.view.WindowManager;youtParams; importandroid.widget.ImageButton;publicclassSurfaceViewPlayVideoextendsActivityimplementsOnClickListener{SurfaceView surfaceView;ImageButton play, pause, stop;MediaPlayer mPlayer;// 记录当前视频的播放位置2324252627282930313233343536373839404142434445 intposition;@OverridepublicvoidonCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(yout.main);// 获取界面中的3个按钮play = (ImageButton) findViewById(R.id.play);pause = (ImageButton) findViewById(R.id.pause);stop = (ImageButton) findViewById(R.id.stop);// 为3个按钮的单击事件绑定事件监听器play.setOnClickListener(this);pause.setOnClickListener(this);stop.setOnClickListener(this);// 创建MediaPlayermPlayer =newMediaPlayer();surfaceView = (SurfaceView)this.findViewById(R.id.surfaceView);// 设置播放时打开屏幕surfaceView.getHolder().setKeepScreenOn(true);surfaceView.getHolder().addCallback(newSurfaceListener());}4647484950515253545556575859606162636465666768 @OverridepublicvoidonClick(View source){try{switch(source.getId()){// 播放按钮被单击caseR.id.play:play();break;// 暂停按钮被单击caseR.id.pause:if(mPlayer.isPlaying()) {mPlayer.pause();}else{mPlayer.start();}break;// 停止按钮被单击6970717273747576777879808182838485868788899091 caseR.id.stop:if(mPlayer.isPlaying()) mPlayer.stop();break;}}catch(Exception e){e.printStackTrace();}}privatevoidplay()throwsIOException{mPlayer.reset();mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); // 设置需要播放的视频mPlayer.setDataSource("/mnt/sdcard/movie.3gp");// 把视频画面输出到SurfaceViewmPlayer.setDisplay(surfaceView.getHolder()); //①mPlayer.prepare();// 获取窗口管理器WindowManager wManager = getWindowManager();DisplayMetrics metrics =newDisplayMetrics();92 93 94 95 96979899100101102103104105106107108109110111112113114// 获取屏幕大小wManager.getDefaultDisplay().getMetrics(metrics); // 设置视频保持纵横比缩放到占满整个屏幕surfaceView.setLayoutParams(newLayoutParams(metrics.widthPixels , mPlayer.getVideoHeight() * metrics.widthPixels / mPlayer.getVideoWidth()));mPlayer.start();}privateclassSurfaceListenerimplementsSurfaceHolder.Callback {@OverridepublicvoidsurfaceChanged(SurfaceHolder holder,intformat, intwidth,intheight){}@OverridepublicvoidsurfaceCreated(SurfaceHolder holder){if(position >0){try115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 {// 开始播放play();// 并直接从指定位置开始播放 mPlayer.seekTo(position);position =0;}catch(Exception e){e.printStackTrace();}}}@OverridepublicvoidsurfaceDestroyed(SurfaceHolder holder) {}}// 当其他Activity 被打开,暂停播放@OverrideprotectedvoidonPause()138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 {if(mPlayer.isPlaying()){// 保存当前的播放位置position = mPlayer.getCurrentPosition(); mPlayer.stop();}super.onPause();}@OverrideprotectedvoidonDestroy(){// 停止播放if(mPlayer.isPlaying()) mPlayer.stop(); // 释放资源mPlayer.release();super.onDestroy();}}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

本文讲的是“android 视频播放器”,并附有播放器源代码1.开发环境:eclipse3.6ADT-0.9.7AVD1.62.程序运行效果A.启动AVD(虚拟设备)在应用程序界面主界面,我们可以看到“艾文播放器”B.点击打开后,会播放默认的一个coco的广告C.点击标题栏的按钮可以打开文件浏览器D.点击视频文件,会提示使用的播放器E.选择“艾文视频播放器”打开后,按ctrl+f12,切换到横屏,发现视频并没有中断,而是继续播放3.源码分析A.图片都是网上找的,还有就是自己收藏的地方翻出来的,不多讲了。

B.布局文件main.xml:期中包含一个videoview,用于播放视频图像titlebar.xml:主视图的标题栏布局,主要用于添加一个菜单按钮,点击后打开文件浏览器myfile.xml:为文件浏览器布局C.VideoPlay.javaview plaincopy to clipboardprint?1.package com.bestaone;2.3.import android.app.Activity;4.import android.content.Intent;5.import .Uri;6.import android.os.Bundle;7.import android.util.Log;8.import android.view.View;9.import android.view.View.OnClickListener;10.import android.view.Window;11.import android.view.WindowManager;12.import android.widget.ImageButton;13.import android.widget.MediaController;14.import android.widget.TextView;15.import android.widget.VideoView;16.17.public class VideoPlay extends Activity {18.19. private VideoView videoView;20. private static int index = 0;21.22.@Override23. public void onCreate(Bundle savedInstanceState) {24. super.onCreate(savedInstanceState);25. requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);26. setContentView(yout.main);27. getWindow().setFlags(youtParams.FLAG_FULLSCREEN, WindoyoutParams.FLAG_FULLSCREEN);//28. //设置标题栏的布局29. getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, yout.titlebar);30. //这个空间暂时没用31. final TextView titleTV = (TextView) findViewById(R.id.title);32. titleTV.setText("");33. ImageButton titleButton = (ImageButton) findViewById(R.id.titleButton);34. //为按钮添加鼠标点击事件35. titleButton.setOnClickListener(new OnClickListener() {36.@Override37. public void onClick(View v) {38. Intent intent = new Intent();39. intent.setClass(VideoPlay.this, MyFile.class);40. //打开MyFile activity41. startActivity(intent);42. }43. });44. Intent intent = getIntent();45. String value = intent.getDataString();46. videoView = (VideoView) findViewById(R.id.VideoView01);47. if(value==null){48. //加载默认视频49. videoView.setVideoURI(Uri.parse("android.resource://com.bestaone/" + R.drawable.coco));50. }else{51. //通过文件浏览器传过来的视频路径,播放52. videoView.setVideoPath(value);53. }54. videoView.setMediaController(new MediaController(VideoPlay.this));55. videoView.requestFocus();56. }57.58. //启动59.@Override60. protected void onStart() {61. super.onStart();62. Log.i("mp4", "@@@ on start");63. }64.65.@Override66. protected void onResume() {67. super.onResume();68. videoView.seekTo(index);69. videoView.start();70. Log.i("mp4", "@@@ on resume");71. }72.73. //暂停74.@Override75. protected void onPause() {76. super.onPause();77. Log.i("mp4", "@@@ on pause");78. }79.80. //停止81.@Override82. protected void onStop() {83. super.onStop();MyFile.javaview plaincopy to clipboardprint?1.package com.bestaone;2.3.import java.io.File;4.import java.util.ArrayList;5.import java.util.List;6.7.import android.app.ListActivity;8.import android.content.Intent;9.import .Uri;10.import android.os.Bundle;11.import android.view.KeyEvent;12.import android.view.View;13.import android.widget.AdapterView;14.import android.widget.AdapterView.OnItemLongClickListener;15.import android.widget.Button;16.import android.widget.EditText;17.import android.widget.ImageButton;18.import android.widget.ListView;19.import android.widget.TextView;20.import android.widget.Toast;21.22.public class MyFile extends ListActivity implements OnItemLongClickListener {23.24. //支持的视频格式25. private final String[][] FILE_MapTable = {26.27. // {后缀名, MIME类型}28. { ".3gp", "video/3gpp" },29. { ".mov", "video/quicktime" },30. { ".avi", "video/x-msvideo" },31. { ".rmvb", "audio/x-pn-realaudio" },32. { ".wmv", "audio/x-ms-wmv" }33.34. };35.36. private List<String> items = null; // items:存放显示的名称37. private List<String> paths = null; // paths:存放文件路径38. private List<String> sizes = null; // sizes:文件大小39. private String rootPath = "/"; // rootPath:起始文件夹40. private TextView path_edit;41. private ImageButton rb_qry;42. private int isZoom = 0;43. private int isOpen = 0;44.45.46. /**47. * 重写返回键功能:返回上一级文件夹48. */49.@Override50. public boolean onKeyDown(int keyCode, KeyEvent event) {51. // 是否触发按键为back键52. if (keyCode == KeyEvent.KEYCODE_BACK) {53. path_edit = (EditText) findViewById(R.id.path_edit);54. File file = new File(path_edit.getText().toString());55. if (rootPath.equals(path_edit.getText().toString())) {56. return super.onKeyDown(keyCode, event);57. } else {58. getFileDir(file.getParent());59. return true;60. }61. // 如果不是back键正常响应62. } else {63. return super.onKeyDown(keyCode, event);64. }65. }66.67.@Override68. protected void onCreate(Bundle icicle) {69. super.onCreate(icicle);70. setContentView(yout.myfile);71.72. path_edit = (EditText) findViewById(R.id.path_edit);73. rb_qry = (ImageButton) findViewById(R.id.qry_button);74. rb_qry.setOnClickListener(listener_qry);75. getListView().setOnItemLongClickListener(this);76. getFileDir(rootPath);77. }78.79. Button.OnClickListener listener_qry = new Button.OnClickListener() {80. public void onClick(View arg0) {81. File file = new File(path_edit.getText().toString());82. if (file.exists()) {83. if (file.isFile()) {84. openFile(file);85. } else {86. getFileDir(path_edit.getText().toString());87. }88. } else {89. Toast.makeText(MyFile.this, "找不到该位置,请确定位置是否正确!",Toast.LENGTH_SHORT).show();90. }91. }92. };93.94. /**95. * 设置ListItem被点击时要做的动作96. */97.@Override98. protected void onListItemClick(ListView l, View v, int position, long id) {99. File file = new File(paths.get(position));100. fileOrDirHandle(file);101. }102.103.104. /**105. * 处理文件或者目录的方法106. * @param file107. * @param flag108. */109. private void fileOrDirHandle(final File file) {110. if (file.isDirectory()) {111. getFileDir(file.getPath());112. } else {113. openFile(file);114. }115. }116.117. /**118. * 取得文件结构的方法119. * @param filePath120. */121. private void getFileDir(String filePath) {122. /* 设置目前所在路径 */123. path_edit.setText(filePath);124. items = new ArrayList<String>();125. paths = new ArrayList<String>();126. sizes = new ArrayList<String>();127. File f = new File(filePath);128. File[] files = f.listFiles();129. if (files != null) {130. /* 将所有文件添加ArrayList中 */131. for (int i = 0; i < files.length; i++) {132. if (files[i].isDirectory()) {133. items.add(files[i].getName());134. paths.add(files[i].getPath());135. sizes.add("");136. }137. }138.139. for (int i = 0; i < files.length; i++) {140. if (files[i].isFile()) {141. String fileName = files[i].getName();142. int index = stIndexOf(".");143. if(index>0){144. String endName = fileName.substring(index,fileName.length()).toLowe rCase();145. String type = null;146. for(int x=0; x<FILE_MapTable.length; x++){147. //支持的格式,才会在文件浏览器中显示148. if(endName.equals(FILE_MapTable[x][0])){149. type = FILE_MapTable[x][1];150. break;151. }152. }153. if(type!=null){154. items.add(files[i].getName());155. paths.add(files[i].getPath());156. sizes.add(MyUtil.fileSizeMsg(files[i]));157. }158. }159. }160. }161. }162. /* 使用自定义的MyAdapter来将数据传入ListActivity */163. setListAdapter(new FileListAdapter(this, items, paths, sizes, isZoom)); 164. }165.166.167. /**168. * 打开文件169. * @param f170. */171. private void openFile(File f) {172. Intent intent = new Intent();173. intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);174. intent.setAction(android.content.Intent.ACTION_VIEW);175. // 跳出列表供选择176. String type = "video/*";177. if (isOpen == 0) {178. type = MyUtil.getMIMEType(f, true);179. }180. // 设置intent的file与MimeType181. intent.setDataAndType(Uri.fromFile(f), type);182.// intent.putExtra("path", "sms_context");183. startActivity(intent);184. }185.186.@Override187. public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, 188. long arg3) {189. // TODO Auto-generated method stub190. return false;191. }192.193.}。

相关文档
最新文档