4K大视频浏览器无法正常播放解决方案
概述
公司内部将完整视频视频存放在网络共享盘中,通过tomcat影响静态地址的方式,让视频通过web的方式在浏览器访问, 发现4K大视频访问很慢很慢,达到无法观看的地步
程序部署在linux服务器,视频存放在windows服务器中
解决方案
1、FFmpeg将视频进行切片
2、通过网络播放生成的.m3u8文件-客户端potplayer
3、通过JSch库远程执行windows命令
FFmpeg将视频进行切片
参考文章: https://juejin.cn/post/7442133979094761513
ffmpeg -i video.mp4 \
-c:v libx264 -c:a aac -f hls -hls_time 10 -hls_list_size 0 \
-hls_segment_filename "output/part%03d.ts" \
output/playlist.m3u8
命令说明
-
-i video.mp4
:输入视频文件。 -
-c:v libx264
:使用 H.264 编解码器对视频进行压缩。 -
-c:a aac
:使用 AAC 编解码器对音频进行压缩。 -
-f hls
:设置输出格式为 HLS,生成.m3u8
播放列表和.ts
片段。 -
-hls_time 10
:指定每个.ts
片段的时长为 10 秒。 -
-hls_list_size 0
:指定播放列表的大小为 0,意味着播放列表可以无限增长,直到视频播放完成。 -
-hls_segment_filename "output/part%03d.ts"
:指定切片文件的命名规则,%03d
表示按照 3 位数字进行编号(例如part000.ts
,part001.ts
)。 -
output/playlist.m3u8
:指定生成的.m3u8
播放列表文件。
LINUX远程执行WINDOWS命令
- 引入maven坐标
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.55</version>
</dependency>
- 自测demo代码案例
package com.llan.ftp.study;
import cn.hutool.core.io.file.FileNameUtil;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
public class SSHRemoteCommandExecutor {
public static void main(String[] args) {
String command = "D:\\tools\\ffmpeg\\bin\\ffmpeg.exe -i \"D:\\视频 完整 地址.mp4\" -c:v libx264 -c:a aac -f hls -hls_time 60 -hls_list_size 0 -hls_segment_filename \"D:\\视频输出地址\\自定义视频名称_%06d.ts\" \"D:\\视频输出地址\\自定义视频名称.m3u8\""; //要执行的Windows命令,路径中包含特殊字符需要转义,路径中包含空格则需要将整个路径使用双引号包住
execCommand(command);
}
public static String execCommand(String command) {
String host = "服务器ip";
String user = "服务器用户名";
String password = "服务器密码";
int port = 22; // 默认SSH端口
try {
JSch jsch = new JSch();
Session session = jsch.getSession(user, host, port);
session.setPassword(password);
session.setConfig("StrictHostKeyChecking", "no"); // 忽略主机密钥检查
session.connect();
ChannelExec channel = (ChannelExec) session.openChannel("exec");
channel.setCommand(command);
channel.setErrStream(System.err);
channel.connect();
InputStream in = channel.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF-8"));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
// 等待命令执行完成
while (!channel.isClosed()) {
Thread.sleep(100);
}
int exitStatus = channel.getExitStatus();
if (exitStatus == 0) {
System.out.println("Folder created or already exists.");
} else {
System.out.println("Failed to create folder.");
}
channel.disconnect();
session.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}