Android 使用Vitamio打造自己的万能播放器(7)——在线播放(下载视频)
前言
本章将实现非常实用的功能——下载在线视频。涉及到多线程、线程更新ui等技术,还需思考产品的设计,如何将新加的功能更好的融入到现有的产品中,并不是简单的加一个界面就行了,欢迎大家交流产品设计和技术细节实现!
系列
1、android 使用vitamio打造自己的万能播放器(1)——准备
2、android 使用vitamio打造自己的万能播放器(2)—— 手势控制亮度、音量、缩放
3、android 使用vitamio打造自己的万能播放器(3)——本地播放(主界面、视频列表)
4、android 使用vitamio打造自己的万能播放器(4)——本地播放(快捷搜索、数据存储)
5、android 使用vitamio打造自己的万能播放器(5)——在线播放(播放优酷视频)
6、android 使用vitamio打造自己的万能播放器(6)——在线播放(播放列表)
正文
一、目标
本章实现视频下载的功能
使用说明:进入在线视频,点击播放时将弹出选择框询问播放还是下载,点击下载后进度条将在本地视频顶部显示。如果想边看便下载,请直接点击本地播放列表中正在下载的视频。
二、实现(部分主要实现代码)
filedownloadhelper
public class filedownloadhelper { private static final string tag = "filedownloadhelper"; /** 线程池 */ private threadpool mpool = new threadpool(); /** 开始下载 */ public static final int message_start = 0; /** 更新进度 */ public static final int message_progress = 1; /** 下载结束 */ public static final int message_stop = 2; /** 下载出错 */ public static final int message_error = 3; /** 中途终止 */ private volatile boolean misstop = false; private handler mhandler; public volatile hashmap<string, string> mdownloadurls = new hashmap<string, string>(); public filedownloadhelper(handler handler) { if (handler == null) throw new illegalargumentexception("handler不能为空!"); this.mhandler = handler; } public void stopall() { misstop = true; mpool.stop(); } public void newdownloadfile(final string url) { newdownloadfile(url, environment.getexternalstoragedirectory() + "/" + fileutils.geturlfilename(url)); } /** * 下载一个新的文件 * * @param url * @param savepath */ public void newdownloadfile(final string url, final string savepath) { if (mdownloadurls.containskey(url)) return; else mdownloadurls.put(url, savepath); mpool.start(new runnable() { @override public void run() { mhandler.sendmessage(mhandler.obtainmessage(message_start, url)); httpclient client = new defaulthttpclient(); httpget get = new httpget(url); inputstream inputstream = null; fileoutputstream outputstream = null; try { httpresponse response = client.execute(get); httpentity entity = response.getentity(); final int size = (int) entity.getcontentlength(); inputstream = entity.getcontent(); if (size > 0 && inputstream != null) { outputstream = new fileoutputstream(savepath); int ch = -1; byte[] buf = new byte[1024]; //每秒更新一次进度 new timer().schedule(new timertask() { @override public void run() { try { fileinputstream fis = new fileinputstream(new file(savepath)); int downloadedsize = fis.available(); if (downloadedsize >= size) cancel(); mhandler.sendmessage(mhandler.obtainmessage(message_progress, downloadedsize, size, url)); } catch (exception e) { } } }, 50, 1000); while ((ch = inputstream.read(buf)) != -1 && !misstop) { outputstream.write(buf, 0, ch); } outputstream.flush(); } } catch (exception e) { log.e(tag, e.getmessage(), e); mhandler.sendmessage(mhandler.obtainmessage(message_error, url + ":" + e.getmessage())); } finally { try { if (outputstream != null) outputstream.close(); } catch (ioexception ex) { } try { if (inputstream != null) inputstream.close(); } catch (ioexception ex) { } } mdownloadurls.remove(url); mhandler.sendmessage(mhandler.obtainmessage(message_stop, url)); } }); } }
代码说明:
a. threadpool是线程池,请参照项目代码。
b. 这里使用了time定时来刷进度,而没有直接在write数据时更新进度,这样的原因时每秒write较高,更新ui过于频繁,可能导致超时等问题。
handle
public handler mdownloadhandler = new handler() { @override public void handlemessage(message msg) { pfile p; string url = msg.obj.tostring(); switch (msg.what) { case filedownloadhelper.message_start://开始下载 p = new pfile(); p.path = mparent.mfiledownload.mdownloadurls.get(url); p.title = new file(p.path).getname(); p.status = 0; p.file_size = 0; if (mdownloadadapter == null) { mdownloadadapter = new fileadapter(getactivity(), new arraylist<pfile>()); mdownloadadapter.add(p, url); mtemplistview.setadapter(mdownloadadapter); mtemplistview.setvisibility(view.visible); } else { mdownloadadapter.add(p, url); mdownloadadapter.notifydatasetchanged(); } break; case filedownloadhelper.message_progress://正在下载 p = mdownloadadapter.getitem(url); p.temp_file_size = msg.arg1; p.file_size = msg.arg2; int status = (int) ((msg.arg1 * 1.0 / msg.arg2) * 10); if (status > 10) status = 10; p.status = status; mdownloadadapter.notifydatasetchanged(); break; case filedownloadhelper.message_stop://下载结束 p = mdownloadadapter.getitem(url); filebusiness.insertfile(getactivity(), p); break; case filedownloadhelper.message_error: toast.maketext(getactivity(), url, toast.length_long).show(); break; } super.handlemessage(msg); } };
代码说明:
a. mtemplistview是新增的,默认是隐藏,请参见项目代码layout部分。
b. 下载流程:开始(显示mtemplistview) -> 正在下载(更新进度图片和大小) -> 完成(入裤)
dialog
if (fileutils.isvideooraudio(url)) { dialog dialog = new alertdialog.builder(getactivity()).seticon(android.r.drawable.btn_star).settitle("播放/下载").setmessage(url).setpositivebutton("播放", new onclicklistener() { @override public void onclick(dialoginterface dialog, int which) { intent intent = new intent(getactivity(), videoplayeractivity.class); intent.putextra("path", url); startactivity(intent); } }).setneutralbutton("下载", new onclicklistener() { @override public void onclick(dialoginterface dialog, int which) { mainfragmentactivity activity = (mainfragmentactivity) getactivity(); activity.mfiledownload.newdownloadfile(url); toast.maketext(getactivity(), "正在下载 .." + fileutils.geturlfilename(url) + " ,可从本地视频查看进度!", toast.length_long).show(); } }).setnegativebutton("取消", null).create(); dialog.show(); return true; }
三、下载
至本章节往后,代码均不再提供下载,请移步google code:
以上就是对android vitamio 开发播放器下载视频播放器的资料整理,有需要开发android播放器的朋友可以参考下。
推荐阅读
-
Android 使用Vitamio打造自己的万能播放器(9)—— 在线播放 (在线电视)
-
Android 使用Vitamio打造自己的万能播放器(2)—— 手势控制亮度、音量、缩放
-
Android 使用Vitamio打造自己的万能播放器(7)——在线播放(下载视频)
-
Android 使用Vitamio打造自己的万能播放器(6)——在线播放(播放列表)
-
Android 使用Vitamio打造自己的万能播放器(5)——在线播放(播放优酷视频)
-
Android 使用Vitamio打造自己的万能播放器(4)——本地播放(快捷搜索、数据存储)
-
Android 使用Vitamio打造自己的万能播放器(1)——准备