You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
149 lines
4.9 KiB
149 lines
4.9 KiB
/*
|
|
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
|
*
|
|
* 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.arialyy.aria.m3u8;
|
|
|
|
import com.arialyy.aria.core.common.RecordHandler;
|
|
import com.arialyy.aria.core.download.DTaskWrapper;
|
|
import com.arialyy.aria.core.download.DownloadEntity;
|
|
import com.arialyy.aria.core.download.M3U8Entity;
|
|
import com.arialyy.aria.core.inf.IRecordHandler;
|
|
import com.arialyy.aria.core.listener.IEventListener;
|
|
import com.arialyy.aria.core.loader.AbsLoader;
|
|
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
|
|
import com.arialyy.aria.util.ALog;
|
|
import com.arialyy.aria.util.FileUtil;
|
|
import java.io.BufferedReader;
|
|
import java.io.File;
|
|
import java.io.FileInputStream;
|
|
import java.io.FileNotFoundException;
|
|
import java.io.FileOutputStream;
|
|
import java.io.IOException;
|
|
import java.io.InputStreamReader;
|
|
import java.nio.charset.Charset;
|
|
|
|
public abstract class BaseM3U8Loader extends AbsLoader {
|
|
protected M3U8TaskOption mM3U8Option;
|
|
|
|
public BaseM3U8Loader(IEventListener listener, DTaskWrapper wrapper) {
|
|
super(listener, wrapper);
|
|
mM3U8Option = (M3U8TaskOption) wrapper.getM3u8Option();
|
|
mTempFile = new File(wrapper.getEntity().getFilePath());
|
|
}
|
|
|
|
@Override protected long delayTimer() {
|
|
return 1000;
|
|
}
|
|
|
|
/**
|
|
* 获取ts文件保存路径
|
|
*
|
|
* @param dirCache 缓存目录
|
|
* @param threadId ts文件名
|
|
*/
|
|
public static String getTsFilePath(String dirCache, int threadId) {
|
|
return String.format("%s/%s.ts", dirCache, threadId);
|
|
}
|
|
|
|
protected String getCacheDir() {
|
|
String cacheDir = mM3U8Option.getCacheDir();
|
|
if (!new File(cacheDir).exists()) {
|
|
FileUtil.createDir(cacheDir);
|
|
}
|
|
return cacheDir;
|
|
}
|
|
|
|
/**
|
|
* 创建索引文件
|
|
*/
|
|
public boolean generateIndexFile(boolean isLive) {
|
|
File tempFile =
|
|
new File(String.format(M3U8InfoThread.M3U8_INDEX_FORMAT, getEntity().getFilePath()));
|
|
if (!tempFile.exists()) {
|
|
ALog.e(TAG, "源索引文件不存在");
|
|
return false;
|
|
}
|
|
FileInputStream fis = null;
|
|
FileOutputStream fos = null;
|
|
try {
|
|
String cacheDir = getCacheDir();
|
|
fis = new FileInputStream(tempFile);
|
|
fos = new FileOutputStream(getEntity().getFilePath());
|
|
BufferedReader reader = new BufferedReader(new InputStreamReader(fis));
|
|
String line;
|
|
int i = 0;
|
|
while ((line = reader.readLine()) != null) {
|
|
byte[] bytes;
|
|
if (line.startsWith("#EXTINF")) {
|
|
fos.write(line.concat("\r\n").getBytes(Charset.forName("UTF-8")));
|
|
String tsPath = getTsFilePath(cacheDir, mRecord.threadRecords.get(i).threadId);
|
|
bytes = tsPath.concat("\r\n").getBytes(Charset.forName("UTF-8"));
|
|
reader.readLine(); // 继续读一行,避免写入源索引文件的切片地址
|
|
i++;
|
|
} else if (line.startsWith("#EXT-X-KEY")) {
|
|
M3U8Entity m3U8Entity = getEntity().getM3U8Entity();
|
|
String keyInfo = String.format("#EXT-X-KEY:METHOD=%s,URI=%s,IV=%s\r\n", m3U8Entity.method,
|
|
m3U8Entity.keyPath, m3U8Entity.iv);
|
|
bytes = keyInfo.getBytes(Charset.forName("UTF-8"));
|
|
} else {
|
|
bytes = line.concat("\r\n").getBytes(Charset.forName("UTF-8"));
|
|
}
|
|
fos.write(bytes, 0, bytes.length);
|
|
}
|
|
// 直播的索引文件需要在结束的时候才写入结束标志
|
|
if (isLive) {
|
|
fos.write("#EXT-X-ENDLIST".concat("\r\n").getBytes(Charset.forName("UTF-8")));
|
|
}
|
|
|
|
fos.flush();
|
|
return true;
|
|
} catch (FileNotFoundException e) {
|
|
e.printStackTrace();
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
} finally {
|
|
try {
|
|
if (fis != null) {
|
|
fis.close();
|
|
}
|
|
if (fos != null) {
|
|
fos.close();
|
|
}
|
|
if (tempFile.exists()) {
|
|
FileUtil.deleteFile(tempFile);
|
|
}
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
@Override public long getCurrentLocation() {
|
|
return isRunning() ? getStateManager().getCurrentProgress() : getEntity().getCurrentProgress();
|
|
}
|
|
|
|
@Override protected IRecordHandler getRecordHandler(AbsTaskWrapper wrapper) {
|
|
RecordHandler handler = new RecordHandler(wrapper);
|
|
M3U8RecordAdapter adapter = new M3U8RecordAdapter((DTaskWrapper) wrapper);
|
|
handler.setAdapter(adapter);
|
|
return handler;
|
|
}
|
|
|
|
protected DownloadEntity getEntity() {
|
|
return (DownloadEntity) mTaskWrapper.getEntity();
|
|
}
|
|
}
|
|
|