Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in / Register
Toggle navigation
Y
yzg-util
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
YZG
yzg-util
Commits
86500002
Commit
86500002
authored
Nov 12, 2021
by
yanxia54
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of
http://git.tbd.yanzuoguang.com/yzg/yzg-util
into xy
parents
b005cd9b
77349a9a
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
270 additions
and
0 deletions
+270
-0
HlsDownloader.java
...ge/src/main/java/com/yanzuoguang/media/HlsDownloader.java
+270
-0
No files found.
yzg-util-image/src/main/java/com/yanzuoguang/media/HlsDownloader.java
0 → 100644
View file @
86500002
package
com
.
yanzuoguang
.
media
;
import
com.yanzuoguang.util.helper.HttpHelper
;
import
java.io.*
;
import
java.net.URL
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.UUID
;
import
java.util.regex.Matcher
;
import
java.util.regex.Pattern
;
/**
* m3mu文件下载
*
* @author 颜佐光
*/
public
class
HlsDownloader
{
public
static
Pattern
pattern
=
Pattern
.
compile
(
".*ts"
);
/**
* 下载uuid
*/
private
String
uuid
;
/**
* 源地址
*/
private
String
originUrlPath
;
/**
*
*/
private
String
preUrlPath
;
/**
* 文件根目录
*/
private
String
rootPath
;
/**
*
*/
private
String
fileName
;
/**
* 当前视频 ts 文件存储临时目录
*/
private
String
folderPath
;
/**
* 线程数量
*/
private
int
threadQuantity
=
10
;
public
HlsDownloader
(
String
originUrlPath
,
String
preUrlPath
,
String
rootPath
)
{
this
.
uuid
=
UUID
.
randomUUID
().
toString
().
replaceAll
(
"-"
,
""
);
this
.
originUrlPath
=
originUrlPath
;
this
.
preUrlPath
=
preUrlPath
;
this
.
rootPath
=
rootPath
;
this
.
fileName
=
uuid
+
".mp4"
;
this
.
folderPath
=
rootPath
+
File
.
separator
+
uuid
;
File
file
=
new
File
(
folderPath
);
if
(!
file
.
exists
())
{
file
.
mkdirs
();
}
}
public
int
getThreadQuantity
()
{
return
threadQuantity
;
}
public
void
setThreadQuantity
(
int
threadQuantity
)
{
this
.
threadQuantity
=
threadQuantity
;
}
public
String
download
(
boolean
isAsync
)
throws
Exception
{
String
indexStr
=
getIndexFile
();
List
urlList
=
analysisIndex
(
indexStr
);
HashMap
<
Integer
,
String
>
keyFileMap
=
new
HashMap
<>();
if
(
isAsync
)
{
downLoadIndexFileAsync
(
urlList
,
keyFileMap
);
while
(
keyFileMap
.
size
()
<
urlList
.
size
())
{
//System.out.println("当前下载数量"+keyFileMap.size());
Thread
.
sleep
(
3000
);
}
}
else
{
keyFileMap
=
downLoadIndexFile
(
urlList
);
}
return
composeFile
(
keyFileMap
);
}
/* 下载索引文件 */
public
String
getIndexFile
()
throws
Exception
{
URL
url
=
new
URL
(
originUrlPath
);
String
content
=
""
;
for
(
int
i
=
0
;
i
<
4
;
i
++)
{
//这里的循环是当下载直播流的时候,一次下载只能有一个ts文件,这里我循环了四次,下载四个ts文件,在合成视频。
//下载资源
try
{
BufferedReader
in
=
new
BufferedReader
(
new
InputStreamReader
(
url
.
openStream
(),
"UTF-8"
));
System
.
err
.
println
(
in
.
readLine
());
String
line
;
while
((
line
=
in
.
readLine
())
!=
null
)
{
content
+=
line
+
"\n"
;
}
in
.
close
();
}
catch
(
Exception
e
)
{
System
.
err
.
println
(
"错误为:"
);
System
.
err
.
println
(
e
);
}
}
return
content
;
}
/* 解析索引文件 */
public
List
analysisIndex
(
String
content
)
throws
Exception
{
List
<
String
>
list
=
new
ArrayList
<
String
>();
Matcher
ma
=
pattern
.
matcher
(
content
);
while
(
ma
.
find
())
{
list
.
add
(
ma
.
group
());
}
return
list
;
}
/* 下载视频片段 */
public
HashMap
downLoadIndexFile
(
List
<
String
>
urlList
)
{
HashMap
<
Integer
,
String
>
keyFileMap
=
new
HashMap
<>();
for
(
int
i
=
0
;
i
<
urlList
.
size
();
i
++)
{
String
subUrlPath
=
urlList
.
get
(
i
);
String
fileOutPath
=
folderPath
+
File
.
separator
+
i
+
".ts"
;
keyFileMap
.
put
(
i
,
fileOutPath
);
try
{
HttpHelper
.
downToLocal
(
preUrlPath
+
subUrlPath
,
fileOutPath
);
System
.
out
.
println
(
"成功:"
+
(
i
+
1
)
+
"/"
+
urlList
.
size
());
}
catch
(
Exception
e
)
{
System
.
err
.
println
(
"失败:"
+
(
i
+
1
)
+
"/"
+
urlList
.
size
());
}
}
return
keyFileMap
;
}
public
void
downLoadIndexFileAsync
(
List
<
String
>
urlList
,
HashMap
<
Integer
,
String
>
keyFileMap
)
throws
Exception
{
int
downloadForEveryThread
=
(
urlList
.
size
()
+
threadQuantity
-
1
)
/
threadQuantity
;
if
(
downloadForEveryThread
==
0
)
{
downloadForEveryThread
=
urlList
.
size
();
}
for
(
int
i
=
0
;
i
<
urlList
.
size
();
i
+=
downloadForEveryThread
)
{
int
startIndex
=
i
;
int
endIndex
=
i
+
downloadForEveryThread
-
1
;
if
(
endIndex
>=
urlList
.
size
())
{
endIndex
=
urlList
.
size
()
-
1
;
}
new
DownloadThread
(
urlList
,
startIndex
,
endIndex
,
keyFileMap
).
start
();
}
}
/**
* 视频片段合成
*
* @param keyFileMap 文件段列表
* @return
* @throws Exception
*/
private
String
composeFile
(
HashMap
<
Integer
,
String
>
keyFileMap
)
throws
Exception
{
if
(
keyFileMap
.
isEmpty
())
{
return
null
;
}
// todo: 输出文件,需要封装成函数
String
fileOutPath
=
rootPath
+
File
.
separator
+
fileName
;
// 订单输出文件流
try
(
FileOutputStream
fileOutputStream
=
new
FileOutputStream
(
new
File
(
fileOutPath
)))
{
// 按照顺序遍历文件缓存
int
size
=
keyFileMap
.
size
();
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
// 获取当前的 ts 文件
File
file
=
new
File
(
keyFileMap
.
get
(
i
));
if
(!
file
.
exists
())
{
continue
;
}
// 读取文件
FileInputStream
fis
=
new
FileInputStream
(
file
);
// 定义文件缓存
byte
[]
bytes
=
new
byte
[
1024
];
// 读取的文件长度
int
length
=
0
;
// 读取来源文件
while
((
length
=
fis
.
read
(
bytes
))
!=
-
1
)
{
// 写入目标文件
fileOutputStream
.
write
(
bytes
,
0
,
length
);
}
}
}
return
fileName
;
}
/**
* 下载线程
*/
private
class
DownloadThread
extends
Thread
{
/**
* 下载地址列表
*/
private
List
<
String
>
urlList
;
/**
* 开始索引
*/
private
int
startIndex
;
/**
* 结束索引
*/
private
int
endIndex
;
/**
* 本地存储缓存地址
*/
private
HashMap
<
Integer
,
String
>
keyFileMap
;
/**
* 构造函数
*
* @param urlList
* @param startIndex
* @param endIndex
* @param keyFileMap
*/
public
DownloadThread
(
List
<
String
>
urlList
,
int
startIndex
,
int
endIndex
,
HashMap
<
Integer
,
String
>
keyFileMap
)
{
this
.
urlList
=
urlList
;
this
.
startIndex
=
startIndex
;
this
.
endIndex
=
endIndex
;
this
.
keyFileMap
=
keyFileMap
;
}
@Override
public
void
run
()
{
for
(
int
i
=
startIndex
;
i
<=
endIndex
;
i
++)
{
// 获取源文件地址
String
subUrlPath
=
urlList
.
get
(
i
);
// 获取生成的地址
String
fileOutPath
=
folderPath
+
File
.
separator
+
i
+
".ts"
;
// 写入生成地址到文件列表
keyFileMap
.
put
(
i
,
fileOutPath
);
try
{
// 下载服务器文件
HttpHelper
.
downToLocal
(
preUrlPath
+
subUrlPath
,
fileOutPath
);
// 判断文件是否下载成功
System
.
out
.
println
(
String
.
format
(
"message"
,
"成功"
,
keyFileMap
.
size
()));
}
catch
(
Exception
e
)
{
// 判断文件是否下载失败
System
.
err
.
println
(
String
.
format
(
"message"
,
"失败"
,
keyFileMap
.
size
()));
}
}
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment