/*
* Copyright (c) 2015 [1076559197@qq.com | tchen0707@gmail.com]
*
* Licensed under the Apache License, Version 2.0 (the "License”);
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.youku.service.download;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Notification;
import android.os.Parcel;
import android.os.Parcelable;
import com.baseproject.utils.Logger;
import com.youku.player.YoukuPlayerApplication;
import com.youku.player.ui.R;
import com.youku.player.util.PlayerUtil;
/**
* DownloadInfo.下载对象
*
* @author 刘仲男 qq81595157@126.com
* @version v3.5
* @created time 2012-11-5 下午1:16:02
*/
public final class DownloadInfo implements Parcelable, Comparable<DownloadInfo> {
public final static int STATE_INIT = -1;
public final static int STATE_DOWNLOADING = 0;
public final static int STATE_FINISH = 1;
public final static int STATE_EXCEPTION = 2;
public final static int STATE_PAUSE = 3;
public final static int STATE_CANCEL = 4;
public final static int STATE_WAITING = 5;
public final static int EXCEPTION_NO_SDCARD = 1;// 无SD卡
public final static int EXCEPTION_NO_NETWORK = 2;// 无网络
public final static int EXCEPTION_NO_SPACE = 3;// 无空间
public final static int EXCEPTION_NO_COPYRIGHT = 4;// 无版权
public final static int EXCEPTION_NO_RESOURCES = 5;// 无资源
public final static int EXCEPTION_HTTP_NOT_FOUND = 6;// 网络404错误
public final static int EXCEPTION_TIMEOUT = 7;// 网络超时
public final static int EXCEPTION_WRITE_ERROR = 8;// 写入info文件写入错误
public final static int EXCEPTION_UNKNOWN_ERROR = 9;// 未知错误
/** 网站高清 */
public final static int FORMAT_MP4 = 1;
public final static int FORMAT_3GP = 2;
// public final static int FORMAT_FLV = 3;
public final static int FORMAT_3GPHD = 4;
/** 网站标清flv */
public final static int FORMAT_FLV = 5;
public final static int FORMAT_M3U8 = 6;
/** 网站超清 */
public final static int FORMAT_HD2 = 7;
/** 格式标签字符 */
public final static String[] FORMAT_STRINGS = new String[] { "", "mp4",
"3gp", "flv", "3gphd", "flvhd", "m3u8", "hd2" };
/** 格式后缀名 */
public final static String[] FORMAT_POSTFIX = new String[] { "", "mp4",
"3gp", "flv", "3gp", "flv", "m3u8", "hd2" };
/** **************************** 以下为必须字段 ******************************************/
/** 视频标题 */
public String title;
/** 视频id */
public String videoid;
/** 视频格式类型:普通、高清等 */
public int format;
/** 语种信息 */
public String language;
/** 剧集id */
public String showid;
/** 剧集标题 */
public String showname;
/** 剧集集数号 */
public int show_videoseq;
/** 剧集总集数 */
public int showepisode_total;
/** 视频类型 */
public String cats;
/** 视频总时长 */
public int seconds;
/** 每个分片时间 */
public int[] segsSeconds;
/** 视频缓存状态 */
public int state = STATE_INIT;
/** **************************** end ******************************************/
/** **************************** 下载未完成时的必须字段 ******************************************/
/** 下载任务id */
public String taskId;
// /** 文件下载线程 */
public FileDownloadThread thread;
/** 该文件的总大小 */
public long size;
/** 已下载完成的文件的大小 */
public long downloadedSize;
/** 创建时间 */
public long createTime;
/** -------------分片信息---------------- */
/** 分片总数量 */
public int segCount;
/** 正在缓存的分片id(正在缓存第几个分片) */
public int segId = 1;
/** 正在缓存的分片地址(这个地址是真实地址,不会过期) */
public String segUrl;
/** 正在缓存的分片已下载大小 */
public long segDownloadedSize;
/** 每个分片大小(数组) */
public long[] segsSize;
/** 每个分片地址(数组)(假地址,每次请求起3小时候后过期失效) */
public String[] segsUrl;
/** 防盗链所需字段 */
public String token;
/** 防盗链所需字段 */
public String oip;
/** 防盗链所需字段 */
public String sid;
/** 防盗链所需字段 */
public String[] segsfileId;
/** **************************** end ******************************************/
/** **************************** 以下为非必须字段 ******************************************/
/** 本地已播放时长(单位:秒) */
public int playTime;
/** 最后播放时间点 (单位:毫秒) */
public long lastPlayTime;
/** 缩略图地址 */
public String imgUrl;
/** (每次)开始缓存的时间 */
public long startTime;
/** 最后一次获得url的时间 */
public long getUrlTime;
public long finishTime;
public long lastUpdateTime;
private int exceptionId;
public double progress;
/** -------------内存中信息---------------- */
/** 保存路径 SD/videoid/ */
public String savePath;
// public DownloadListener downloadInnerListener;// 内部listener,不可调用
public DownloadListener downloadListener;// 外部listener,可调用
public Notification notification;
/** 下载异常后重试次数 */
public int retry = 0;
/** 缩略图是否正在下载中 */
public boolean isThumbnailDownloading = false;
/** **************************** end ******************************************/
public DownloadInfo() {
}
protected DownloadInfo(Parcel in) {
title = in.readString();
videoid = in.readString();
format = in.readInt();
language = in.readString();
showid = in.readString();
showname = in.readString();
show_videoseq = in.readInt();
showepisode_total = in.readInt();
cats = in.readString();
seconds = in.readInt();
state = in.readInt();
taskId = in.readString();
size = in.readLong();
downloadedSize = in.readLong();
createTime = in.readLong();
segCount = in.readInt();
segId = in.readInt();
segUrl = in.readString();
segDownloadedSize = in.readLong();
token = in.readString();
oip = in.readString();
sid = in.readString();
playTime = in.readInt();
lastPlayTime = in.readLong();
imgUrl = in.readString();
startTime = in.readLong();
getUrlTime = in.readLong();
finishTime = in.readLong();
lastUpdateTime = in.readLong();
exceptionId = in.readInt();
progress = in.readDouble();
savePath = in.readString();
retry = in.readInt();
isThumbnailDownloading = in.readByte() != 0x00;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(title);
dest.writeString(videoid);
dest.writeInt(format);
dest.writeString(language);
dest.writeString(showid);
dest.writeString(showname);
dest.writeInt(show_videoseq);
dest.writeInt(showepisode_total);
dest.writeString(cats);
dest.writeInt(seconds);
dest.writeInt(state);
dest.writeString(taskId);
dest.writeLong(size);
dest.writeLong(downloadedSize);
dest.writeLong(createTime);
dest.writeInt(segCount);
dest.writeInt(segId);
dest.writeString(segUrl);
dest.writeLong(segDownloadedSize);
dest.writeString(token);
dest.writeString(oip);
dest.writeString(sid);
dest.writeInt(playTime);
dest.writeLong(lastPlayTime);
dest.writeString(imgUrl);
dest.writeLong(startTime);
dest.writeLong(getUrlTime);
dest.writeLong(finishTime);
dest.writeLong(lastUpdateTime);
dest.writeInt(exceptionId);
dest.writeDouble(progress);
dest.writeString(savePath);
dest.writeInt(retry);
dest.writeByte((byte) (isThumbnailDownloading ? 0x01 : 0x00));
}
@SuppressWarnings("unused")
public static final Parcelable.Creator<DownloadInfo> CREATOR = new Parcelable.Creator<DownloadInfo>() {
@Override
public DownloadInfo createFromParcel(Parcel in) {
return new DownloadInfo(in);
}
@Override
public DownloadInfo[] newArray(int size) {
return new DownloadInfo[size];
}
};
/**
* TODO Return是否是剧集
*/
public boolean isSeries() {
if (showid == null || showid.length() == 0)
return false;
if (cats == null || cats.length() == 0)
return true;
int typeId = getTypeId(cats, showepisode_total);
switch (typeId) {
case Constants.MOVIE_SINGLE:
case Constants.SHOW_SINLE:
case Constants.VARIETY_SINGLE:
case Constants.CARTOON_SINGLE:
case Constants.MEMORY_SINGLE:
case Constants.EDUCATION_SINGLE:
case Constants.SPECIAL_SINGLE:
return false;
case Constants.MUSIC:
if (showepisode_total <= 1)// 音乐类单集,不按文件夹处理
return false;
default:
break;
}
return true;
}
/**
* TODO Comment:视频类型
*
* @param type
* 视频类型
* @param total
* 剧集总集数
* @return
*/
public static int getTypeId(String type, int total) {
int typeId = 0;
if ((YoukuPlayerApplication.context.getResources().getString(R.string.detail_tv))
.equals(type)) {
if (total > 1) {
typeId = Constants.SHOW_MANY;
} else {
typeId = Constants.SHOW_SINLE;
}
} else if ((YoukuPlayerApplication.context.getResources()
.getString(R.string.detail_movie)).equals(type)) {
if (total > 1) {
typeId = Constants.MOVIE_MANY;
} else {
typeId = Constants.MOVIE_SINGLE;
}
} else if ((YoukuPlayerApplication.context.getResources()
.getString(R.string.detail_variety)).equals(type)) {
if (total > 1) {
typeId = Constants.VARIETY_MANY;
} else {
typeId = Constants.VARIETY_SINGLE;
}
} else if ((YoukuPlayerApplication.context.getResources()
.getString(R.string.detail_cartoon)).equals(type)) {
if (total > 1) {
typeId = Constants.CARTOON_MANY;
} else {
typeId = Constants.CARTOON_SINGLE;
}
} else if ((YoukuPlayerApplication.context.getResources()
.getString(R.string.detail_music)).equals(type)) {
typeId = Constants.MUSIC;
} else if ((YoukuPlayerApplication.context.getResources()
.getString(R.string.detail_memory)).equals(type)) {
if (total > 1) {
typeId = Constants.MEMORY_MANY;
} else {
typeId = Constants.MEMORY_SINGLE;
}
} else if ((YoukuPlayerApplication.context.getResources()
.getString(R.string.detail_education)).equals(type)) {
if (total > 1) {
typeId = Constants.EDUCATION_MANY;
} else {
typeId = Constants.EDUCATION_SINGLE;
}
} else if ((YoukuPlayerApplication.context.getResources().getString(R.string.detail_ugc))
.equals(type)) {
typeId = Constants.UGC;
} else if ((YoukuPlayerApplication.context.getResources()
.getString(R.string.detail_special)).equals(type)) {
if (total > 1) {
typeId = Constants.SPECIAL_MANY;
} else {
typeId = Constants.SPECIAL_SINGLE;
}
}
return typeId;
}
public void setState(int state) {
Logger.d("sgh","download info setState(): " + state);
if(downloadListener != null)
Logger.d("sgh","not null");
else
Logger.e("sgh","null");
// if (this.state != state) {
this.state = state;
switch (state) {
case STATE_DOWNLOADING:
if (downloadListener != null)
downloadListener.onStart();
break;
case STATE_PAUSE:
if (downloadListener != null)
downloadListener.onPause();
break;
case STATE_FINISH:
if (downloadListener != null)
downloadListener.onFinish();
break;
case STATE_CANCEL:
if (downloadListener != null)
downloadListener.onCancel();
break;
case STATE_EXCEPTION:
if (downloadListener != null)
downloadListener.onException();
break;
case STATE_WAITING:
if (downloadListener != null)
downloadListener.onWaiting();
break;
}
// }
}
public int getState() {
return state;
}
public int getExceptionId() {
return exceptionId;
}
/**
* TODO 状态是否可能改变
*
* @return
*/
public boolean stateMaybeChange() {
return state == STATE_DOWNLOADING || state == STATE_WAITING
|| state == STATE_EXCEPTION || state == STATE_PAUSE
|| state == STATE_INIT;
}
public double getProgress() {
if (progress == 0) {
progress = ((double) downloadedSize * 100) / size;
}
return progress;
}
private double lastProgress = 0;
public int iseditState;
public void setProgress(double progress) {
this.progress = progress;
if (progress != lastProgress && (progress - lastProgress) >= 0.1
&& System.currentTimeMillis() - lastUpdateTime >= 2000) {
this.lastProgress = progress;
// if (downloadInnerListener != null)
// downloadInnerListener.onProgressChange(progress);
if (downloadListener != null)
downloadListener.onProgressChange(progress);
}
}
public void setExceptionId(int exceptionId) {
this.exceptionId = exceptionId;
}
public String getExceptionInfo() {
return getExceptionInfo(exceptionId);
// return exceptionInfo;
}
public static String getExceptionInfo(int exceptionId) {
switch (exceptionId) {
case EXCEPTION_NO_SDCARD:// 无SD卡
return YoukuPlayerApplication.context.getString(R.string.download_no_sdcard);
case EXCEPTION_NO_NETWORK:// 无网络
return YoukuPlayerApplication.context.getString(R.string.download_no_network);
case EXCEPTION_NO_SPACE:// 无空间
return YoukuPlayerApplication.context.getString(R.string.download_no_space);
case EXCEPTION_NO_COPYRIGHT:// 无版权
return YoukuPlayerApplication.context.getString(R.string.download_unknown_error);
case EXCEPTION_NO_RESOURCES:// 无资源
return YoukuPlayerApplication.context.getString(R.string.download_unknown_error);
case EXCEPTION_HTTP_NOT_FOUND:// 网络404错误
return YoukuPlayerApplication.context.getString(R.string.download_unknown_error);
case EXCEPTION_TIMEOUT:// 网络超时
return YoukuPlayerApplication.context.getString(R.string.download_timeout);
case EXCEPTION_WRITE_ERROR:// 写入info文件写入错误
return YoukuPlayerApplication.context.getString(R.string.download_write_fail);
case EXCEPTION_UNKNOWN_ERROR:// 未知错误
return YoukuPlayerApplication.context.getString(R.string.download_unknown_error);
default:
break;
}
return "";
}
private static final String KEY_title = "title";
private static final String KEY_vid = "vid";
private static final String KEY_showid = "showid";
private static final String KEY_showname = "showname";
private static final String KEY_format = "format";
private static final String KEY_show_videoseq = "show_videoseq";
private static final String KEY_showepisode_total = "showepisode_total";
private static final String KEY_cats = "cats";
private static final String KEY_seconds = "seconds";
private static final String KEY_size = "size";
private static final String KEY_segcount = "segcount";
private static final String KEY_segsseconds = "segsseconds";
private static final String KEY_segssize = "segssize";
private static final String KEY_taskid = "taskid";
private static final String KEY_downloadedsize = "downloadedsize";
private static final String KEY_segdownloadedsize = "segdownloadedsize";
private static final String KEY_segID = "segstep";
private static final String KEY_createtime = "createtime";
private static final String KEY_starttime = "starttime";
private static final String KEY_getUrlTime = "getUrlTime";
private static final String KEY_finishtime = "finishtime";
// private static final String KEY_segsUrl = "segsUrl";
private static final String KEY_state = "state";
private static final String KEY_exceptionid = "exceptionid";
private static final String KEY_progress = "progress";
private static final String KEY_language = "language";
private static final String KEY_playTime = "playTime";
private static final String KEY_lastPlayTime = "lastPlayTime";
private static final String KEY_savepath = "savepath";
public JSONObject toJSONObject() {
JSONObject o = new JSONObject();
try {
o.put(KEY_title, title);
o.put(KEY_vid, videoid);
o.put(KEY_showid, showid);
o.put(KEY_showname, showname);
o.put(KEY_format, format);
o.put(KEY_show_videoseq, show_videoseq);
o.put(KEY_showepisode_total, showepisode_total);
o.put(KEY_cats, cats);
o.put(KEY_seconds, seconds);
o.put(KEY_size, size);
o.put(KEY_segcount, segCount);
o.put(KEY_segsseconds, PlayerUtil.join(segsSeconds));
o.put(KEY_segssize, PlayerUtil.join(segsSize));
o.put(KEY_taskid, taskId);
o.put(KEY_downloadedsize, downloadedSize);
o.put(KEY_segdownloadedsize, segDownloadedSize);
o.put(KEY_segID, segId);
o.put(KEY_createtime, createTime);
o.put(KEY_starttime, startTime);
o.put(KEY_getUrlTime, getUrlTime);
o.put(KEY_finishtime, finishTime);
// o.put(KEY_segsUrl, YoukuUtil.join(segsUrl));
o.put(KEY_state, state);
o.put(KEY_exceptionid, exceptionId);
o.put(KEY_progress, progress);
o.put(KEY_language, language);
o.put(KEY_playTime, playTime);
o.put(KEY_lastPlayTime, lastPlayTime);
o.put(KEY_savepath, savePath);
} catch (JSONException e) {
Logger.e("toJSONObject", e);
o = null;
}
return o;
}
public static DownloadInfo jsonToDownloadInfo(String jsonString) {
JSONObject o;
try {
if (jsonString == null || jsonString.length() == 0)
return null;
o = new JSONObject(jsonString.trim());
} catch (JSONException e) {
Logger.e("Download_DownloadInfo",
"DownloadInfo#jsonToDownloadInfo()", e);
return null;
}
DownloadInfo info = new DownloadInfo();
info.title = o.optString(KEY_title);
info.videoid = o.optString(KEY_vid);
info.showid = o.optString(KEY_showid);
info.format = o.optInt(KEY_format);
info.show_videoseq = o.optInt(KEY_show_videoseq);
info.showepisode_total = o.optInt(KEY_showepisode_total);
info.cats = o.optString(KEY_cats);
info.seconds = o.optInt(KEY_seconds);
info.size = o.optLong(KEY_size);
info.segCount = o.optInt(KEY_segcount);
info.segsSeconds = PlayerUtil.string2int((o.optString(KEY_segsseconds))
.split(","));
info.segsSize = PlayerUtil.string2long(o.optString(KEY_segssize).split(
","));
// info.segsUrl = TextUtils.isEmpty(o.optString(KEY_segsUrl)) ? new
// String[] {}
// : o.optString(KEY_segsUrl).split(",");
info.taskId = o.optString(KEY_taskid);
info.downloadedSize = o.optInt(KEY_downloadedsize);
info.segDownloadedSize = o.optInt(KEY_segdownloadedsize);
info.segId = o.optInt(KEY_segID, 1);
info.createTime = o.optLong(KEY_createtime);
info.startTime = o.optLong(KEY_starttime);
info.getUrlTime = o.optLong(KEY_getUrlTime);
info.finishTime = o.optLong(KEY_finishtime);
info.state = o.optInt(KEY_state, STATE_INIT);
info.exceptionId = o.optInt(KEY_exceptionid);
info.progress = o.optDouble(KEY_progress, 0);
info.language = o.optString(KEY_language);
info.playTime = o.optInt(KEY_playTime);
info.lastPlayTime = o.optLong(KEY_lastPlayTime);
info.showname = o.optString(KEY_showname);
info.savePath = o.optString(KEY_savepath);
return info;
}
public String getProgressJSONFile() {
JSONObject o = new JSONObject();
try {
o.put(KEY_downloadedsize, downloadedSize);
o.put(KEY_segdownloadedsize, segDownloadedSize);
o.put(KEY_segID, segId);
o.put(KEY_progress, progress);
} catch (JSONException e) {
Logger.e("toJSONObject", e);
return null;
}
return o.toString();
}
public static DownloadInfo parseProgressJSONFile(String jsonString) {
JSONObject o;
try {
if (jsonString == null || jsonString.length() == 0)
return null;
o = new JSONObject(jsonString.trim());
} catch (JSONException e) {
Logger.e("jsonToDownloadInfo", e);
return null;
}
DownloadInfo info = new DownloadInfo();
info.downloadedSize = o.optInt(KEY_downloadedsize);
info.segDownloadedSize = o.optInt(KEY_segdownloadedsize);
info.segId = o.optInt(KEY_segID, 1);
info.progress = o.optDouble(KEY_progress, 0);
return info;
}
/** 是否按剧集排序,true按剧集排序;false按时间排序 */
public static boolean compareBySeq = true;
@Override
public int compareTo(DownloadInfo info) {
if (compareBySeq) {
if (this.show_videoseq > info.show_videoseq) {
return 1;
} else {
return -1;
}
} else {
if (this.createTime > info.createTime) {
return 1;
} else {
return -1;
}
}
}
@Override
public String toString() {
JSONObject o = toJSONObject();
return o == null ? "" : o.toString();
}
}