android 自定义视频播放器之2/1

很久没更新博客,相信大家年后都比较忙。

今天给大家带来了一款视频播放器,首先确认的得有几点。

1、首先得有个播放视频的view;

2、加点额外功能进去左边上下滑动调节亮度,右边上下滑动调节声量;

3、视频当然得有快进和快退,左右滑动快进和快退;

4、可全屏播放;

5、暂时只做了离线播放。下篇博客再去研究在线播放。视频路径 这是视频本地路径,视频资源的话你们自己去找,文件夹会自动创建,放在该文件夹下面就可以了

private String Path = Environment.getExternalStorageDirectory() + “/wywVideo/

首先先贴上效果图:

咱们根据效果图一步一步的来,先进行布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.wyw.activity.FullVideoView
        android:id="@+id/video_VideoView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <ImageView
        android:id="@+id/video_img"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
    <ImageView
        android:id="@+id/video_img_center_speed"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        />

    <RelativeLayout
        android:id="@+id/video_relative_right"
        android:layout_width="300dp"
        android:layout_height="match_parent"
        android:layout_above="@+id/video_relative_buttom"
        android:layout_alignParentRight="true"
        android:background="@color/lightgray_50" >

        <ImageView
            android:id="@+id/video_imageView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:src="@drawable/right_video_img" />

        <ListView
            android:id="@+id/video_listview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toRightOf="@+id/video_imageView"
            android:paddingRight="10dp" >
        </ListView>
    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/video_relative_buttom"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:paddingTop="10dp"
        android:paddingBottom="10dp"
        android:background="@color/gray_50" >

        <ImageView
            android:id="@+id/video_img_last"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="40dp"
            android:layout_centerVertical="true"
            android:src="@drawable/last_video_selector" />

        <ImageView
            android:id="@+id/video_img_start"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="20dp"
            android:layout_centerVertical="true"
            android:layout_toRightOf="@+id/video_img_last"
            android:src="@drawable/start_video_df" />

        <ImageView
            android:id="@+id/video_img_next"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="20dp"
            android:layout_centerVertical="true"
            android:layout_toRightOf="@+id/video_img_start"
            android:src="@drawable/next_video_selector" />

        <ImageView
            android:id="@+id/video_img_voice"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="20dp"
            android:layout_centerVertical="true"
            android:layout_toLeftOf="@+id/video_img_full"
            android:src="@drawable/right_show_img" />

        <ImageView
            android:id="@+id/video_img_full"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginRight="30dp"
            android:src="@drawable/big_video_selector" />

        <TextView
            android:id="@+id/video_txt_current_time"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginLeft="10dp"
            android:layout_toRightOf="@+id/video_img_next"
            android:text="@string/play_time"
            android:textColor="@color/white" />

        <ImageView
            android:id="@+id/video_videoview_pres_bg"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:layout_toLeftOf="@+id/video_txt_max_time"
            android:layout_toRightOf="@+id/video_txt_current_time"
            android:background="@drawable/video_num_bg" />

        <ImageView
            android:id="@+id/video_videoview_pres_front"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:layout_toRightOf="@+id/video_txt_current_time"
            android:background="@drawable/video_num_front" />

        <TextView
            android:id="@+id/video_txt_max_time"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginRight="10dp"
            android:layout_toLeftOf="@+id/video_img_voice"
            android:text="@string/play_time"
            android:textColor="@color/white" />
    </RelativeLayout>

    <ImageView
        android:id="@+id/video_img_center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:src="@drawable/video_brightness_bg"
        android:visibility="gone" />

    <FrameLayout
        android:id="@+id/video_frame"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_below="@+id/video_img_center"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="-30dp"
        android:visibility="gone" >

        <ImageView
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:background="@drawable/video_num_bg" />

        <ImageView
            android:id="@+id/video_img_pres_front"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:background="@drawable/video_num_front" />
    </FrameLayout>

</RelativeLayout>

该布局的图为

在这里咱们先把显示亮度和声音的布局隐藏掉,当需要的时候在显示出来。

现在则需要自定义一个可全屏播放的自定义VideoView出来代码如下:

package com.wyw.activity;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.VideoView;

public class FullVideoView extends VideoView {

    public FullVideoView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        // TODO Auto-generated constructor stub
    }
    public FullVideoView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }
    public FullVideoView(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = getDefaultSize(0, widthMeasureSpec);
        int height = getDefaultSize(0, heightMeasureSpec);
        setMeasuredDimension(width, height);
    };
}

好,现在呢关键的部分来了。

首先呢得有滑动根据手势来区分和调节音量还是亮度或者是快进快退。

然后根据大小动态显示各自的进度条。然后呢在抬起手势中该隐藏的隐藏该初始化的初始化。播放时间呢我是用了一个延时线程,1000毫秒执行一次也就是1秒执行一次,正在播放长度大于视频总长度的话呢我就会吧当前线程给干掉。这样就达到了时间1秒1跳的效果。我们还需要把视频长度转换成时间。

好了,说了这么多应该也差不多能明白大概意思了,该动真家伙了。

下面贴代码:

package com.wyw.activity;

import java.io.File;
import java.util.ArrayList;

import com.wyw.videodemo.R;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.media.ThumbnailUtils;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore.Video.Thumbnails;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.TextView;

/**
 * 视频播放界面
 *
 * @author WangYuWen
 * @version 1.0
 * @date 2015年3月5日
 * @Copyright: Copyright (c) 2014 Shenzhen Utoow Technology Co., Ltd. All rights
 *             reserved.
 */
public class MainActivity extends BaseActivity {

    /** 右边列表控件 */
    private ListView listview;
    /** 右边缩放控件 */
    private RelativeLayout right_relative;
    /** 上一首 */
    private ImageView img_last;
    /** 下一首 */
    private ImageView img_next;
    /** 播放 */
    private ImageView img_start;
    /** 全屏播放 */
    private ImageView img_full;
    /** 加减声音 */
    private ImageView img_voice;
    /** 列表适配器 */
    private VideoListAdapter adapter;
    /** 列表集合 */
    private ArrayList<VideoListBean> list;
    /** 播放视频的背景图片 */
    private ImageView video_img;

    /** 亮度或者声音的图片 */
    private ImageView img_center;
    /** 调节进度 */
    private ImageView img_pres_white;
    /** 底部视图栏 */
    private RelativeLayout buttom_relative;

    private View view;

    private FullVideoView video_VideoView;
    /** 当前播放时间 */
    private TextView txt_current_time;
    /** 总时间 */
    private TextView txt_max_time;
    /** 当前播放进度 */
    private ImageView img_white;
    /** 播放进度背景 */
    private ImageView img_bg;
    /** 拖放进度 */
    private ImageView img_center_speed;

    private AudioManager mAudioManager;
    /** 最大音量 */
    private int mMaxVolume;
    /** 当前声音 */
    private int mVolume = -1;
    /** 当前亮度 */
    private float mBrightness = -1f;
    /** 屏幕宽度 */
    private int width;
    /** 屏幕高度 */
    private int height;
    /** 手势 */
    private GestureDetector mGestureDetector;
    /** 视频总长度 */
    private long mVideo_total_length;
    /** 视频当前长度 */
    private long mVideo_current_length;
    /** 按下手势时的X点 */
    private float downX = 0;
    /** 按下手势时的Y点 */
    private float downY = 0;
    /** 移动手势时的Y点 */
    private float moveY = 0;
    /** 移动手势时的X点 */
    private float moveX = 0;
    /** 记录上一次移动手势时的X点 */
    private float OldMoveX = 0;
    /** 记录上一次移动手势时的y点 */
    private float OldMoveY = 0;
    /** 双数才执行(在用到的地方有详细的解释) */
    private int evens = 0;

    /** 是否显示全屏 */
    private boolean isVH = true;
    /** 是否快进了 */
    private boolean isVideo = false;
    /** 是否调节了音量 */
    private boolean isVoice = false;
    /** 是否调节了亮度 */
    private boolean isBright = false;
    /** 是否点击了开始播放 */
    private boolean isStart = false;
    /** 当前播放位置 */
    private int index_position = 0;

    private static final int handKey = 123;

    /** 视频路径 这是视频本地路径,资源的话你们自己去找,文件夹有创建,*/
    private String Path = Environment.getExternalStorageDirectory() + "/wywVideo/";

    @Override
    protected int getContentViewId() {
        return R.layout.activity_video_list;
    }

    @SuppressWarnings("deprecation")
    @Override
    protected void findViews() {
        img_last = (ImageView) findViewById(R.id.video_img_last);
        img_start = (ImageView) findViewById(R.id.video_img_start);
        img_next = (ImageView) findViewById(R.id.video_img_next);
        img_full = (ImageView) findViewById(R.id.video_img_full);
        img_voice = (ImageView) findViewById(R.id.video_img_voice);
        video_img = (ImageView) findViewById(R.id.video_img);

        img_center = (ImageView) findViewById(R.id.video_img_center);
        img_pres_white = (ImageView) findViewById(R.id.video_img_pres_front);

        txt_current_time = (TextView) findViewById(R.id.video_txt_current_time);
        txt_max_time = (TextView) findViewById(R.id.video_txt_max_time);
        img_white = (ImageView) findViewById(R.id.video_videoview_pres_front);
        img_bg = (ImageView) findViewById(R.id.video_videoview_pres_bg);
        img_center_speed = (ImageView) findViewById(R.id.video_img_center_speed);

        video_VideoView = (FullVideoView) findViewById(R.id.video_VideoView);

        view = findViewById(R.id.video_frame);
        // 获取屏幕宽度
        width = getWindowManager().getDefaultDisplay().getWidth();
        // 获取屏幕高度
        height = getWindowManager().getDefaultDisplay().getHeight();

        right_relative = (RelativeLayout) findViewById(R.id.video_relative_right);
        buttom_relative = (RelativeLayout) findViewById(R.id.video_relative_buttom);
        // 右边试图宽度为屏幕宽度的3分之1
        right_relative.getLayoutParams().width = width / 3;

        listview = (ListView) findViewById(R.id.video_listview);

        widgetListener();
    }

    @Override
    protected void init() {

        mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        mMaxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);

        File file = new File(Path);
        if (!file.exists()) {
            file.mkdirs();
        }

        list = new ArrayList<VideoListBean>();

        mGestureDetector = new GestureDetector(this, new MyGestureListener());

        adapter = new VideoListAdapter(MainActivity.this, list);
        listview.setAdapter(adapter);

        new Thread(runnable2).start();
    }

    /** 点击事件 */
    private void widgetListener() {
        /** 列表点击事件 */
        listview.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                index_position = position;
                txt_max_time.setText(R.string.play_time);
                img_start.setImageResource(R.drawable.start_video_df);
                video_VideoView.stopPlayback();
                setVideo(position);
            }
        });

        /** 上一首 */
        img_last.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                index_position--;
                if (index_position>=0) {
                    txt_max_time.setText(R.string.play_time);
                    img_start.setImageResource(R.drawable.start_video_df);
                    video_VideoView.stopPlayback();
                    setVideo(index_position);
                }else{
                    index_position=0;
                }
            }
        });
        /** 下一首 */
        img_next.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                index_position++;
                img_start.setImageResource(R.drawable.start_video_df);
                txt_max_time.setText(R.string.play_time);
                video_VideoView.stopPlayback();
                setVideo(index_position);
            }
        });

        /** 播放 */
        img_start.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                video_img.setVisibility(View.GONE);
                if (video_VideoView.isPlaying()) {
                    video_VideoView.pause();
                    img_start.setImageResource(R.drawable.start_video_df);
                } else {
                    mVideo_total_length = video_VideoView.getDuration();// 获取视频总长度
                    // 设置总时长(总长度换算成时间)
                    txt_max_time.setText(length2time(mVideo_total_length));
                    isStart = true;
                    video_VideoView.start();
                    img_start.setImageResource(R.drawable.pause_video_df);
                    handler.postAtTime(runnable, 0);
                }
            }
        });

        /** 全屏 */
        img_full.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                if (isVH) {
                    WindowManager.LayoutParams params = getWindow().getAttributes();
                    params.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
                    getWindow().setAttributes(params);
                    getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);

                    right_relative.setVisibility(View.GONE);
                    buttom_relative.setVisibility(View.GONE);

                    isVH = false;
                } else {
                    WindowManager.LayoutParams params = getWindow().getAttributes();
                    params.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN);
                    getWindow().setAttributes(params);
                    getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);

                    buttom_relative.setVisibility(View.VISIBLE);
                    isVH = true;
                }
            }
        });
        /** 是否显示右边视图点击事件 */
        img_voice.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                if (right_relative.isShown()) {
                    right_relative.setVisibility(View.GONE);
                } else {
                    right_relative.setVisibility(View.VISIBLE);
                }
            }
        });
        /** 右边视图 */
        right_relative.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                right_relative.setVisibility(View.GONE);
            }
        });
    }

    private Runnable runnable2 = new Runnable() {

        @Override
        public void run() {
            doSearch(Path);
            Message message = handler.obtainMessage();
            message.what = handKey;
            handler.sendMessage(message);
        }
    };

    /**
     * 搜索该路径下面的所有文件
     *
     * @version 1.0
     * @createTime 2015年3月12日,下午2:11:47
     * @updateTime 2015年3月12日,下午2:11:47
     * @createAuthor WangYuWen
     * @updateAuthor WangYuWen
     * @updateInfo (此处输入修改内容,若无修改可不写.)
     *
     * @param path
     */
    private void doSearch(String path) {
        File file = new File(path);

        if (file.exists()) {
            if (file.isDirectory()) {
                File[] fileArray = file.listFiles();
                for (File f : fileArray) {
                    if (f.isDirectory()) {// 判断是否文件夹
                                // 文件夹为true
                        doSearch(f.getPath());
                    } else {
                        if (f.getName().endsWith("mp4") || f.getName().endsWith("3gp")) {
                            VideoListBean bean = new VideoListBean();
                            bean.setVideo_name(f.getName());
                            bean.setVideo_path(f.getAbsolutePath());
                            Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(f.getAbsolutePath(), Thumbnails.MINI_KIND);
                            if (bitmap != null) {
                                bitmap = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth() * 300 / bitmap.getHeight(), 300, true);
                                bean.setVideo_imgbg(bitmap);
                            }
                            list.add(bean);
                        }
                    }
                }
            }
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (mGestureDetector.onTouchEvent(event))
            return true;

        // 处理手势结束
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_UP:
            endGesture();
            break;
        }
        return super.onTouchEvent(event);
    }

    /**
     * 手势结束
     *
     * @version 1.0
     * @createTime 2015年3月5日,上午11:36:43
     * @updateTime 2015年3月5日,上午11:36:43
     * @createAuthor WangYuWen
     * @updateAuthor WangYuWen
     * @updateInfo (此处输入修改内容,若无修改可不写.)
     *
     */
    private void endGesture() {
        if (!isVideo && !isVoice && !isBright) {
            if (right_relative.isShown()) {
                right_relative.setVisibility(View.GONE);
            }
            if (buttom_relative.isShown()) {
                buttom_relative.setVisibility(View.GONE);
            } else {
                buttom_relative.setVisibility(View.VISIBLE);
            }
        }

        isVideo = false;
        isVoice = false;
        isBright = false;

        OldMoveX = 0;
        OldMoveY = 0;

        // 隐藏
        img_center.setVisibility(View.GONE);
        img_center_speed.setVisibility(View.GONE);
        view.setVisibility(View.GONE);
    }

    @SuppressLint("HandlerLeak")
    private Handler handler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            if (msg.what == handKey) {
                setVideo(index_position);
                adapter.notifyDataSetChanged();
            }
        };
    };

    /**
     * 设置Video该播放视频的准备和视频的背景图片
     *
     * @version 1.0
     * @createTime 2015年3月12日,下午2:17:55
     * @updateTime 2015年3月12日,下午2:17:55
     * @createAuthor WangYuWen
     * @updateAuthor WangYuWen
     * @updateInfo (此处输入修改内容,若无修改可不写.)
     *
     * @param position
     */
    @SuppressWarnings("deprecation")
    private void setVideo(int position) {
        if (list.size() > position && position>-1) {
            Drawable drawable = new BitmapDrawable(list.get(position).getVideo_imgbg());
            video_VideoView.setVideoPath(list.get(position).getVideo_path());
            video_VideoView.requestFocus();
            video_img.setVisibility(View.VISIBLE);
            video_img.setBackgroundDrawable(drawable);
        }
    }

    private Runnable runnable = new Runnable() {

        @Override
        public void run() {
            mVideo_current_length = video_VideoView.getCurrentPosition();

            if (mVideo_current_length >= mVideo_total_length) {
                mVideo_current_length = mVideo_total_length;
            }
            /** 设置当前时长 */
            txt_current_time.setText(length2time(mVideo_current_length));
            /** 设置视频进度 */
            LayoutParams layoutParams = (LayoutParams) img_white.getLayoutParams();
            layoutParams.width = (int) (((float) img_bg.getWidth()) / mVideo_total_length * mVideo_current_length);
            img_white.setLayoutParams(layoutParams);

            handler.postDelayed(runnable, 1000);

            if (mVideo_current_length >= mVideo_total_length) {
                handler.removeCallbacks(runnable);
            }

        }
    };

    /**
     * 调节音量
     *
     * @version 1.0
     * @createTime 2015年3月5日,上午11:16:35
     * @updateTime 2015年3月5日,上午11:16:35
     * @createAuthor WangYuWen
     * @updateAuthor WangYuWen
     * @updateInfo (此处输入修改内容,若无修改可不写.)
     *
     * @param num
     */
    private void setVoiceNum(float num) {
        evens++;//这里为什么要用个双数执行呢,因为手势滑动的太快音量只有15,控制了下音量增减速度,不然稍微滑动一下就到了最高或者最低这是我们用户不喜欢看到的。
        mVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);

        if (mVolume < 0) {
            mVolume = 0;
        }
        if (num < 0 && evens % 2 == 0) {
            mVolume -= 1;
        } else if (num > 0 && evens % 2 == 0) {
            mVolume += 1;
        }

        if (mVolume > mMaxVolume) {
            mVolume = mMaxVolume;
        } else if (mVolume < 0) {
            mVolume = 0;
        }

        img_center.setImageResource(R.drawable.video_voice_bg);
        img_center.setVisibility(View.VISIBLE);
        view.setVisibility(View.VISIBLE);

        // 变更声音
        mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, mVolume, 0);

        // 变更进度条
        ViewGroup.LayoutParams lp = img_pres_white.getLayoutParams();
        lp.width = DisplayUtils.dip2px(MainActivity.this, 100) * mVolume / mMaxVolume;
        img_pres_white.setLayoutParams(lp);
    }

    /**
     * 调节视频进度
     *
     * @version 1.0
     * @createTime 2015年3月5日,下午4:48:07
     * @updateTime 2015年3月5日,下午4:48:07
     * @createAuthor WangYuWen
     * @updateAuthor WangYuWen
     * @updateInfo (此处输入修改内容,若无修改可不写.)
     *
     * @param distanceX
     */
    private void onVideoSpeed(float distanceX) {
        mVideo_current_length = video_VideoView.getCurrentPosition();// 当前播放长度

        if (distanceX > 0) {// 往左滑动 --
            img_center_speed.setVisibility(View.VISIBLE);
            img_center_speed.setImageResource(R.drawable.retreat_video);
            mVideo_current_length -= 1000;// 快进之后长度
        } else if (distanceX < 0) {// 往右滑动 ++
            img_center_speed.setVisibility(View.VISIBLE);
            img_center_speed.setImageResource(R.drawable.speed_video);
            mVideo_current_length += 1000;// 快进之后长度
        }

        if (mVideo_current_length >= mVideo_total_length) {
            mVideo_current_length = mVideo_total_length;
        } else if (mVideo_current_length <= 0) {
            mVideo_current_length = 0;
        }
        video_VideoView.seekTo((int) mVideo_current_length);
        // //定位播放在哪个位置
        handler.postDelayed(runnable, 0);
    }

    /**
     * 将进度长度转变为进度时间
     *
     * @version 1.0
     * @createTime 2015年3月5日,下午4:25:05
     * @updateTime 2015年3月5日,下午4:25:05
     * @createAuthor WangYuWen
     * @updateAuthor WangYuWen
     * @updateInfo (此处输入修改内容,若无修改可不写.)
     *
     * @param length
     * @return
     */
    @SuppressLint("DefaultLocale")
    private String length2time(long length) {
        length /= 1000L;
        long minute = length / 60L;
        long hour = minute / 60L;
        long second = length % 60L;
        minute %= 60L;
        return String.format("%02d:%02d:%02d", hour, minute, second);
    }

    /**
     * 调节亮度
     *
     * @version 1.0
     * @createTime 2015年3月5日,上午11:16:44
     * @updateTime 2015年3月5日,上午11:16:44
     * @createAuthor WangYuWen
     * @updateAuthor WangYuWen
     * @updateInfo (此处输入修改内容,若无修改可不写.)
     *
     * @param percent
     */
    private void onBrightnessSlide(float percent) {
        WindowManager.LayoutParams lpa = getWindow().getAttributes();
        mBrightness = lpa.screenBrightness;

        img_center.setImageResource(R.drawable.video_brightness_bg);
        img_center.setVisibility(View.VISIBLE);
        view.setVisibility(View.VISIBLE);

        lpa.screenBrightness = mBrightness + percent;
        if (lpa.screenBrightness > 1.0f) {
            lpa.screenBrightness = 1.0f;
        } else if (lpa.screenBrightness < 0.01f) {
            lpa.screenBrightness = 0.01f;
        }
        getWindow().setAttributes(lpa);
        // 变更亮度进度条
        ViewGroup.LayoutParams lp = img_pres_white.getLayoutParams();
        lp.width = (int) (DisplayUtils.dip2px(MainActivity.this, 100) * lpa.screenBrightness);
        img_pres_white.setLayoutParams(lp);
    }

    private class MyGestureListener extends SimpleOnGestureListener {
        /** 双击 */
        @Override
        public boolean onDoubleTap(MotionEvent e) {
            return true;
        }

        /** 滑动 */
        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            // e1==按下的点 e2==移动的点
            downX = e1.getX();
            downY = e1.getY();
            moveX = e2.getX();
            moveY = e2.getY();
            if (OldMoveX == 0) {
                OldMoveX = downX;
                OldMoveY = downY;
            }
            if (Math.abs(moveY - downY) < Math.abs(moveX - downX) && !isVoice && !isBright && isStart) {
                handler.removeCallbacks(runnable);
                onVideoSpeed((OldMoveX - moveX) / width);
                OldMoveX = moveX;
                isVideo = true;
            } else {
                if (downX > width * 4 / 5 && !isVideo && !isBright) {// 右边滑动
                    setVoiceNum((OldMoveY - moveY) / height);
                    OldMoveY = moveY;
                    isVoice = true;
                } else if (downX < width / 5 && !isVideo && !isVoice) {// 左边滑动
                    onBrightnessSlide((OldMoveY - moveY) / height);
                    OldMoveY = moveY;
                    isBright = true;
                }
            }

            return super.onScroll(e1, e2, distanceX, distanceY);
        }
    }
}

方便一些朋友写,我这里也把适配器和数据集的代码也贴进来。

首先是数据(bean):

package com.wyw.activity;

import android.graphics.Bitmap;

public class VideoListBean{

    /** 视频id */
    private String Video_Id;
    /** 视频名字 */
    private String Video_name;
    /** 视频路径 */
    private String Video_path;
    /** 视频展示配置表-封面图URL */
    private Bitmap Video_imgbg;
    /** 创建时间 */
    private String Create_time;

    public Bitmap getVideo_imgbg() {
        return Video_imgbg;
    }

    public void setVideo_imgbg(Bitmap video_imgbg) {
        Video_imgbg = video_imgbg;
    }

    public String getCreate_time() {
        return Create_time;
    }

    public void setCreate_time(String create_time) {
        Create_time = create_time;
    }

    public String getVideo_Id() {
        return Video_Id;
    }

    public void setVideo_Id(String video_Id) {
        Video_Id = video_Id;
    }

    public String getVideo_name() {
        return Video_name;
    }

    public void setVideo_name(String video_name) {
        Video_name = video_name;
    }

    public String getVideo_path() {
        return Video_path;
    }

    public void setVideo_path(String video_path) {
        Video_path = video_path;
    }

}

适配器:

package com.wyw.activity;

import java.util.ArrayList;
import com.wyw.videodemo.R;

import android.annotation.SuppressLint;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class VideoListAdapter extends BaseAdapter {

    private Context context;

    private ArrayList<VideoListBean> list;

    public VideoListAdapter(Context context,ArrayList<VideoListBean> list){
        this.context=context;
        this.list=list;
    }

    @Override
    public int getCount() {
        return list.size();
    }

    @Override
    public Object getItem(int position) {
        return list.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @SuppressLint("InflateParams")
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final ViewHolder viewHolder;
        final VideoListBean bean = list.get(position);
        if (convertView==null) {
            viewHolder = new ViewHolder();
            convertView = LayoutInflater.from(context).inflate(R.layout.item_video_listview, null);
            viewHolder.img_video = (ImageView) convertView.findViewById(R.id.item_video_img);
            viewHolder.txt_name = (TextView) convertView.findViewById(R.id.item_video_txt_name);
            viewHolder.txt_time = (TextView) convertView.findViewById(R.id.item_video_txt_time);
            convertView.setTag(viewHolder);
        }else{
            viewHolder = (ViewHolder) convertView.getTag();
        }

        viewHolder.txt_name.setText(bean.getVideo_name());
        viewHolder.img_video.setImageBitmap(bean.getVideo_imgbg());

        viewHolder.txt_time.setText(DateUtils.getDay());        

        return convertView;
    }

    private class ViewHolder{
        /**视频图片*/
        private ImageView img_video;
        /**视频名字*/
        private TextView txt_name;
        /**视频时间*/
        private TextView txt_time;
    }

}

隐藏各个控件我觉得应该要有动画才好看,这个就交给你们延伸了。下次呢我会加上动画以及研究下在线播放解码之类的。

希望大家多多关注我的博客,多多支持我。

如有好意见或更好的方式欢迎留言谈论。

尊重原创转载请注明:(http://blog.csdn.net/u013895206) 侵权必究!

下面是地址传送门:

http://download.csdn.net/detail/u013895206/8494817

时间: 2024-10-16 23:11:08

android 自定义视频播放器之2/1的相关文章

Android自定义视频播放器(网络/本地)

最近因公司项目要求需要写一个播放器,自带的又不太好用,也不太好看.自能自定义啦.查看了很多资料,都没有完善的,还好得以为前辈的指点得以完成,感谢Yang.本篇里面我有可能有些地方写得不好(都附上了注释).希望各路大神指点,虚心受教. 先来个图(源码在后面附上) 视频列表里面的数据是本地的,如果你需要使用网络的只需要在此获取服务器的数据展示就行了.播放页面在后面. package com.eteng.moblieplayer.video; import android.content.Conten

Android进阶:自定义视频播放器开发(下)

上一篇文章我们主要讲了视频播放器开发之前需要准备的一个知识,TextureView,用于对图像流的处理.这篇文章开始构建一个基础的视频播放器. 一.准备工作 在之前的文章已经说过了,播放器也是一个view,我们要在这个view上播放视频流.所以我们要自定义一个简单的viewgroup,比如继承FrameLayout.还出就是布局简单,其他控件可以往上面添加.大家见过的视频播放器的控制器都是放在视频的上方的.这样就是用FrameLayout布局是最好的. class SmallVideoPlaye

Android 自定义Gallery浏览图片

之前写的<Android ImageSwitcher和Gallery的使用>一文中提到我在教室一下午为实现那个效果找各种资料.期间在网上找了一个个人觉得比较不错的效果,现在贴图上来: 其实这个效果使用的知识点就是图像的获取.创建.缩放.旋转.Matrix类.Canvas类等,另外就是自定义的Gallery控件. 相信大家都期待马上上代码了吧,嘻嘻.(注释比较多,相信大家都能看懂.) main.xml: <?xml version="1.0" encoding=&quo

Android自定义View探索(一)—生命周期

Activity代码: public class FiveActivity extends AppCompatActivity { private MyView myView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.e("log", "Activity生命周期:onCreate"); setConte

android自定义UI模板图文详解

不知道大家在实际开发中有没有自定义过UI模板?今天花时间研究了一下android中自定义UI模板,与大家分享一下. 每个设计良好的App都是自定义标题栏,在自定义标题栏的过程中大部分人可能都是自定义一个标题的xml文件,然后在需要的地方直接通过include来引用,这比起在每个布局文件中写标题栏已经进化很多了,但仍然不是最简单有效的方法,我们为什么不能自定义一个标题控件呢?今天就带大家自己做一个标题栏控件.效果图如下: 开始啦: 第一步:自定义xml属性 新建一个android项目,在value

Android自定义进度条样式

最近在做一个widget,上面需要一个progressbar,产品经理和设计师给出来的东西是要实现一个圆角的progress和自定义的颜色,研究一小下,分享出来给大家哦. 测试于:Android4.0+ 操作步骤: 1.创建你的layout文件引用progressbar如下,标红处引用你自定的样式: <ProgressBar android:id="@+id/progressDownload" style="?android:attr/progressBarStyleH

Android 自定义RecyclerView 实现真正的Gallery效果

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38173061 ,本文出自:[张鸿洋的博客] 上一篇博客我使用自定义HorizontalScrollView写了一个具有HorizontalScrollView效果和ViewPager特性的横向图片轮播,详见:Android 自定义 HorizontalScrollView 打造再多图片(控件)也不怕 OOM 的横向滑动效果.其实制作横向滚动的不得不说另一个控件,就是Google

Android 自定义 HorizontalScrollView 打造再多图片(控件)也不怕 OOM 的横向滑动效果

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38140505 自从Gallery被谷歌废弃以后,Google推荐使用ViewPager和HorizontalScrollView来实现Gallery的效果.的确HorizontalScrollView可以实现Gallery的效果,但是HorizontalScrollView存在一个很大的问题,如果你仅是用来展示少量的图片,应该是没问题的,但是如果我希望HorizontalScr

Android 自定义UI圆角按钮

Android实际开发中我们一般需要圆角的按钮,一般情况下我们可以让美工做出来相应的按钮图片,然后放上去即可,另外我们可以在布局文件中直接设置,也可以达到一样的效果.下面讲解在布局文件中自定义圆角按钮的小Demo. 代码很简单,实现效果图: 源代码: 源代码: 这里主要是xml布局文件实现: MainActivity: package com.android_drawableresource; import android.app.Activity; import android.os.Bund