android 视频播放器 android videoView 按不同比例缩放 .

2024-01-27 23:32

本文主要是介绍android 视频播放器 android videoView 按不同比例缩放 .,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

http://blog.csdn.net/zhangxu365/article/details/7062429

SeeJoPlayer是我利用业余时间开发的一款免费的视频播放器。主要是现在在网上似乎找不到一个Android平台下的界面美观一点的视频播放器。而作为智能手机操作系统的Android,没有一个像样一点的视频播放器,岂不糗大了。所以,我就写了这么一个砖头并开出源码,希望能引出高手们的美玉来吧!


         下载APK程序         下载源代码         转到eoeMarket发布页




第二部分:源码解析

    SeeJoPlayer不是一个完美的作品,可以说,它在很多地方都不尽如人意。当然一个完美的作品,也不是我写这款播放器的目的。我只是希望以此为引,结合大家共同的智慧开发出一款真正完美强大的Android平台下的国产视频播放器出来。

    SeeJoPlayer有许多不足之处,例如,它只支持系统默认的视频格式,因为它使用系统默认的解码器。这,一方面是因为如果通过软解码的话,播放视频的效率会很受影响,另外最主要的原因当然还是个人水平、精力有限,没办法接着往下做了。如果大家觉得这份代码还多少有些参考价值的话,不妨拿去用。只是希望当你们以此为参考,开发出真正强大的播放器出来的时候,别忘了如果能开放源码的话,一定开放出来。毕竟开源软件就好比能够进化的物种,提供你的DNA出来,让我们共同的软件变得越来越完美吧!

    好了,废话不说了。播放器的全部源码本文中已经提供了下载地址。下面,我就其中我觉得可能值得关注的地方做一些解释。

    一、VideoView与视频比例缩放:

    以前在论坛上也看到有人问过如何实现视频按比例缩放的问题。的确,如果仅仅使用VideoView可能达不到我们想要达到的效果。这就需要我们对VideoView做一些改动,简单的说就是另外写一个类似VideoView的类出来(庆幸Android是开源的)。

    我们可以很方便的获得VideoView的源代码,最简单的方法是直接在GoogleCodeSearch上找“VideoView.java”。所以重写VideoView的过程其实只是在原来的基础上进行一些修改而已,并非一个很麻烦的工作。为什么Android自带的VideoView会保持视频的长宽比而不能让我们很方便的自定义比例呢?我猜想可能Google做Android也是一个很仓促的工程,许多代码并没有考虑得太成熟。

    VideoView的源码中有这样一段代码:

1    @Override
2    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
3        //Log.i("@@@@", "onMeasure");
4        int width = getDefaultSize(mVideoWidth, widthMeasureSpec);
5        int height = getDefaultSize(mVideoHeight, heightMeasureSpec);
6        if (mVideoWidth > 0 && mVideoHeight > 0) {
7            if ( mVideoWidth * height  > width * mVideoHeight ) {
8                //Log.i("@@@", "image too tall, correcting");
9                height = width * mVideoHeight / mVideoWidth;
10            } else if ( mVideoWidth * height  < width * mVideoHeight ) {
11                //Log.i("@@@", "image too wide, correcting");
12                width = height * mVideoWidth / mVideoHeight;
13            } else {
14                //Log.i("@@@", "aspect ratio is correct: " +
15                        //width+"/"+height+"="+
16                        //mVideoWidth+"/"+mVideoHeight);
17            }
18        }
19        //Log.i("@@@@@@@@@@", "setting size: " + width + 'x' + height);
20        setMeasuredDimension(width, height);
21    }
22

    这就是为什么长宽比不能改变的原因了。因为在OnMeasure的时候,就对这个长宽比进行了处理。

    我们把其中处理的代码屏蔽掉,视频大小就可以随着VideoView的长宽改变而改变了。

1    @Override
2    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
3        //Log.i("@@@@", "onMeasure");
4        int width = getDefaultSize(mVideoWidth, widthMeasureSpec);
5        int height = getDefaultSize(mVideoHeight, heightMeasureSpec);
6        /**//*if (mVideoWidth > 0 && mVideoHeight > 0) {
7            if ( mVideoWidth * height  > width * mVideoHeight ) {
8                //Log.i("@@@", "image too tall, correcting");
9                height = width * mVideoHeight / mVideoWidth;
10            } else if ( mVideoWidth * height  < width * mVideoHeight ) {
11                //Log.i("@@@", "image too wide, correcting");
12                width = height * mVideoWidth / mVideoHeight;
13            } else {
14                //Log.i("@@@", "aspect ratio is correct: " +
15                        //width+"/"+height+"="+
16                        //mVideoWidth+"/"+mVideoHeight);
17            }
18        }*/
19        //Log.i("@@@@@@@@@@", "setting size: " + width + 'x' + height);
20        setMeasuredDimension(width,height);
21    }


    二、视频控制菜单与播放界面的层次问题:

    看到过一些别人写的视频播放器,其中有一些朋友老是简简单单的将VideoView和控制界面放在一个LinearLayout中。这样随着控制界面的出现与否,VideoView会随之改变长宽,给人的体验并不很好。所以,我认为VideoView和控制界面最好不要放在同一个层次上。不要偷懒,使用一个FrameLayout或者PopupWindow就可以解决这个问题。例如,我就简简单单地使用了PopupWindow,这个具体实现上,就百花争鸣吧。

    三、视频文件扫描:

    视频文件的扫描,现在想来主要有两种方式:

    第一种就是直接读取媒体库中的视频文件数据库。当Android启动的时候,系统会自动扫描sdcard,并为媒体文件建立(或者更新)数据库。我们可以通过对应的URI来访问数据库,从而得到视频文件的列表:

1    private Uri videoListUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
2
3
4
5    Cursor cursor = getContentResolver().query(videoListUri, new String[]{"_display_name","_data"}, null, null, null);
6        int n = cursor.getCount();
7        cursor.moveToFirst();
8        LinkedList<MovieInfo> playList2 = new LinkedList<MovieInfo>();
9        for(int i = 0 ; i != n ; ++i){
10            MovieInfo mInfo = new MovieInfo();
11            mInfo.displayName = cursor.getString(cursor.getColumnIndex("_display_name"));
12            mInfo.path = cursor.getString(cursor.getColumnIndex("_data"));
13            playList2.add(mInfo);
14            cursor.moveToNext();
15        }  

    这种方法可能是最有效率的了,不过不知为何,媒体库中似乎没有扫描进本身支持的3GP视频格式(也可能我这里是一个特例) 。不过,正是因为这个原因,我才想到有可能需要另外一种最基本的扫描文件系统的方法来扫描视频文件。这就是文件系统的遍历:

1    private void getVideoFile(final LinkedList<MovieInfo> list,File file){
2        
3        file.listFiles(new FileFilter(){
4
5            @Override
6            public boolean accept(File file) {
7                // TODO Auto-generated method stub
8                String name = file.getName();
9                int i = name.indexOf('.');
10                if(i != -1){
11                    name = name.substring(i);
12                    if(name.equalsIgnoreCase(".mp4")||name.equalsIgnoreCase(".3gp")){
13                        
14                        MovieInfo mi = new MovieInfo();
15                        mi.displayName = file.getName();
16                        mi.path = file.getAbsolutePath();
17                        list.add(mi);
18                        return true;
19                    }
20                }else if(file.isDirectory()){
21                    getVideoFile(list, file);
22                }
23                return false;
24            }
25        });
26    }

    当然,随着Android平台下的硬件设备越来越多,越来越强大。我们有理由相信,它以后将不仅仅只支持MP4和3GP格式的视频文件,所以我们必须使用两种方式结合的方法来获得最大的视频集合作为我们的视频列表。

    四、播放过程中进度条progress的设定:

    视频开始播放了,那么一个小麻烦出现了:什么时候设定进度条才更有效率?我这里有一种方法供大家参考,那就是通过Handler自己给自己发消息来达到不断设置进度条的目的。

1    Handler myHandler = new Handler(){
2   
3        @Override
4        public void handleMessage(Message msg) {
5            // TODO Auto-generated method stub
6            
7            switch(msg.what){
8            
9                case PROGRESS_CHANGED:
10                    
11                    int i = vv.getCurrentPosition();
12                    seekBar.setProgress(i);
13                    
14                    i/=1000;
15                    int minute = i/60;
16                    int hour = minute/60;
17                    int second = i%60;
18                    minute %= 60;
19                    playedTextView.setText(String.format("%02d:%02d:%02d", hour,minute,second));
20                    
21                    sendEmptyMessage(PROGRESS_CHANGED);
22                    break;
23

   
    当然,这种方法,需要首先发送一个初始消息来启动。

    五、全屏与非全屏:

    大家都知道,一般一个Activity设置全屏的方法有两种,一是在OnCreate中:

1    @Override   
2    public void onCreate(Bundle icicle) {   
3    super.onCreate(icicle);   
4      
5    requestWindowFeature(Window.FEATURE_NO_TITLE);           
6    Window win = getWindow();   
7    win.setFlags(WindowManager.LayoutParams.NO_STATUS_BAR_FLAG,   
8            WindowManager.LayoutParams.NO_STATUS_BAR_FLAG);   
9      
10    setContentView(R.layout.mylayout);  
11
12
13

    二是在AndroidManifest.xml中:

1<activity android:name=".MyActivity"
2          android:label=""
3          android:theme="@android:style/Theme.NoTitleBar.Fullscreen">


    然而,这两种方法都不能达到我们在视频播放过程中设置全屏与否的目的。因为它们都只能在初始化的时候决定全屏与否。那么我现在要说的就是第三种方法:

1getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

1getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

    这种方法就可以在Activity运行过程中,动态地改变全屏与否。

    六、音量调节:

    音量调节的方法其实很简单,不过有人问到,我就在这里顺便说下:

1        AudioManager am = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
2        setIndex(am.getStreamVolume(AudioManager.STREAM_MUSIC));


    好了,就写这些了吧。可能这些知识有人知道,或者还有些盲点我没有讲到。欢迎大家与我联系,大家一起多多讨论交流,并且整个源码都开放出来了,大家一定可以把来龙去脉弄得一清二楚的!最后,多谢大家听我罗嗦,欢迎使用SeeJoPlayer,欢迎阅读其源码!本文也欢迎大家转载,不过转载请注明出处:http://www.blogjava.net/zh-weir/archive/2010/01/24/310617.html

这篇关于android 视频播放器 android videoView 按不同比例缩放 .的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/651823

相关文章

流媒体平台/视频监控/安防视频汇聚EasyCVR播放暂停后视频画面黑屏是什么原因?

视频智能分析/视频监控/安防监控综合管理系统EasyCVR视频汇聚融合平台,是TSINGSEE青犀视频垂直深耕音视频流媒体技术、AI智能技术领域的杰出成果。该平台以其强大的视频处理、汇聚与融合能力,在构建全栈视频监控系统中展现出了独特的优势。视频监控管理系统EasyCVR平台内置了强大的视频解码、转码、压缩等技术,能够处理多种视频流格式,并以多种格式(RTMP、RTSP、HTTP-FLV、WebS

2. c#从不同cs的文件调用函数

1.文件目录如下: 2. Program.cs文件的主函数如下 using System;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;using System.Windows.Forms;namespace datasAnalysis{internal static

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

uva 10061 How many zero's and how many digits ?(不同进制阶乘末尾几个0)+poj 1401

题意是求在base进制下的 n!的结果有几位数,末尾有几个0。 想起刚开始的时候做的一道10进制下的n阶乘末尾有几个零,以及之前有做过的一道n阶乘的位数。 当时都是在10进制下的。 10进制下的做法是: 1. n阶位数:直接 lg(n!)就是得数的位数。 2. n阶末尾0的个数:由于2 * 5 将会在得数中以0的形式存在,所以计算2或者计算5,由于因子中出现5必然出现2,所以直接一

android-opencv-jni

//------------------start opencv--------------------@Override public void onResume(){ super.onResume(); //通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是 //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存

EasyPlayer.js网页H5 Web js播放器能力合集

最近遇到一个需求,要求做一款播放器,发现能力上跟EasyPlayer.js基本一致,满足要求: 需求 功性能 分类 需求描述 功能 预览 分屏模式 单分屏(单屏/全屏) 多分屏(2*2) 多分屏(3*3) 多分屏(4*4) 播放控制 播放(单个或全部) 暂停(暂停时展示最后一帧画面) 停止(单个或全部) 声音控制(开关/音量调节) 主辅码流切换 辅助功能 屏

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动