package com.zhan_dui.download.alfred.missions;
import com.zhan_dui.utils.m3u8.Element;
import com.zhan_dui.utils.m3u8.Playlist;
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* Created by daimajia on 14-2-28.
*/
public class M3U8Mission extends Mission{
protected int mVideoSegmentCount = -1;
protected int mDownloadedSgementCount = 0;
protected int mTotalVideoDuration;
protected int mDownloadedVideoDuration;
protected int mCurrentPartDownloaded = 0;
private int mReopenCount = 30;
private final int MAX_REOPEN_COUNT = 0;
protected Playlist mM3U8Playlist;
public M3U8Mission(String uri,String saveDirectory,String saveName){
super(uri,saveDirectory,saveName);
}
public M3U8Mission(String uri,String saveDirectory,String saveName,String showName){
super(uri,saveDirectory,saveName,showName);
}
@Override
public void run() {
notifyStart();
BufferedInputStream in = null;
FileOutputStream out = null;
HttpURLConnection httpURLConnection;
try{
httpURLConnection = (HttpURLConnection) new URL(getUri()).openConnection();
in = new BufferedInputStream(httpURLConnection.getInputStream());
out = getSafeOutputStream(getSaveDir(),getSaveName());
mM3U8Playlist = Playlist.parse(in);
for(Element el:mM3U8Playlist){
mTotalVideoDuration += el.getDuration();
}
mVideoSegmentCount = mM3U8Playlist.getElements().size();
notifyMetaDataReady();
byte data[] = new byte[1024];
int count;
int c = 0;
for(Element el :mM3U8Playlist){
HttpURLConnection connection = (HttpURLConnection)new URL(el.getURI().toString()).openConnection();
connection.setConnectTimeout(5000);
in = new BufferedInputStream(connection.getInputStream());
while (isCanceled() == false){
try{
count = in.read(data,0,1024);
if(count == -1){
break;
}
out.write(data,0,count);
mCurrentPartDownloaded += count;
mDownloaded+=count;
notifySpeedChange();
checkPaused();
}catch (Exception e){
//if pause download, it will makes the socket close,and stop the download.
//so we need to reopen it.
//well, maybe a big bug here, maybe cause dead cycle :( so I set a
//max open count to prevent this situation.
mReopenCount++;
if(mReopenCount > MAX_REOPEN_COUNT){
throw new Exception("There is too much open exception.");
}
connection = (HttpURLConnection)new URL(el.getURI().toString()).openConnection();
connection.setRequestProperty("Range","bytes=" + mCurrentPartDownloaded + "-");
connection.setDoOutput(true);
connection.setDoInput(true);
in = new BufferedInputStream(connection.getInputStream());
}
}
mCurrentPartDownloaded = 0;
mDownloadedSgementCount++;
mDownloadedVideoDuration+=el.getDuration();
notifyPercentageChange();
if(isCanceled()){
notifyCancel();
break;
}
}
if(!isCanceled()){
notifyPercentageChange();
notifySuccess();
}
}catch (Exception e){
notifyError(e);
}finally {
try{
if(in!=null) in.close();
if(out!=null) out.close();
}catch (Exception e){
notifyError(e);
}
notifyFinish();
}
}
@Override
public int getPercentage() {
return (int)(mDownloadedVideoDuration * 100.0f/mTotalVideoDuration);
}
public int getSegmentsCount(){
return mVideoSegmentCount;
}
/**
* get m3u8 video duration
* @return the video duration(seconds)
*/
public int getVideoDuration(){
return mTotalVideoDuration;
}
/**
* get m3u8 video downloaded duration(seconds)
* @return
*/
public int getDownloadedDuration(){
return mDownloadedVideoDuration;
}
public int getDownloadedSegmentCount(){
return mDownloadedSgementCount;
}
public int getCurrentSegmentDownloaded(){
return mCurrentPartDownloaded;
}
}