Ver Fonte

解决hls错误,优化代码

MisterZhang há 4 anos atrás
pai
commit
55eedb8dbb

+ 32 - 0
src/main/java/com/zj/thread/MediaStreamReader.java

@@ -0,0 +1,32 @@
+package com.zj.thread;
+
+import java.io.InputStream;
+
+import org.bytedeco.javacv.FFmpegFrameGrabber;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 提供管道流接入
+ * @author ZJ
+ *
+ */
+public class MediaStreamReader {
+
+	@Getter@Setter
+	private InputStream in;
+
+	public MediaStreamReader(InputStream in) {
+		super();
+		this.in = in;
+	}
+	
+	public void init() {
+		FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(in);
+		
+		/**
+		 * 待完善
+		 */
+	}
+}

+ 51 - 0
src/main/java/com/zj/thread/MediaTransfer.java

@@ -1,12 +1,63 @@
 package com.zj.thread;
 
+import java.io.ByteArrayOutputStream;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.bytedeco.ffmpeg.global.avutil;
+import org.bytedeco.javacv.FFmpegLogCallback;
+
+import io.netty.channel.ChannelHandlerContext;
+import lombok.Getter;
+import lombok.Setter;
+
 /**
  * 媒体转换者
  * @author ZJ
  *
  */
 public abstract class MediaTransfer {
+	
+	static {
+		avutil.av_log_set_level(avutil.AV_LOG_ERROR);
+		FFmpegLogCallback.set();
+	}
+
+	/**
+	 * ws客户端
+	 */
+	public ConcurrentHashMap<String, ChannelHandlerContext> wsClients = new ConcurrentHashMap<>();
+	
+	/**
+	 * http客户端
+	 */
+	public ConcurrentHashMap<String, ChannelHandlerContext> httpClients = new ConcurrentHashMap<>();
+	
+	/**
+	 * 当前在线人数
+	 */
+	public int hcSize, wcSize = 0;
 
+	/**
+	 * 用于没有客户端时候的计时
+	 */
+	public int noClient = 0;
+	
+	/**
+	 * flv header
+	 */
+	public byte[] header = null;
+	
+	/**
+	 * 输出流,视频最终会输出到此
+	 */
+	public ByteArrayOutputStream bos = new ByteArrayOutputStream();
+	
+	/**
+	 * 转码回调
+	 */
+	@Getter@Setter
+	public TransferCallback transferCallback;
+	
 //	public void addClient() {
 //		
 //	}

+ 1 - 23
src/main/java/com/zj/thread/MediaTransferFlvByFFmpeg.java

@@ -1,7 +1,6 @@
 package com.zj.thread;
 
 import java.io.BufferedReader;
-import java.io.ByteArrayOutputStream;
 import java.io.DataInputStream;
 import java.io.IOException;
 import java.io.InputStreamReader;
@@ -12,7 +11,6 @@ import java.net.SocketTimeoutException;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map.Entry;
-import java.util.concurrent.ConcurrentHashMap;
 
 import org.bytedeco.javacv.FrameGrabber.Exception;
 
@@ -43,19 +41,6 @@ import lombok.extern.slf4j.Slf4j;
 @Slf4j
 public class MediaTransferFlvByFFmpeg extends MediaTransfer {
 
-	/**
-	 * ws客户端
-	 */
-	private ConcurrentHashMap<String, ChannelHandlerContext> wsClients = new ConcurrentHashMap<>();
-	/**
-	 * http客户端
-	 */
-	private ConcurrentHashMap<String, ChannelHandlerContext> httpClients = new ConcurrentHashMap<>();
-
-	/**
-	 * flv header
-	 */
-	private byte[] header = null;
 	/**
 	 * 相机
 	 */
@@ -73,16 +58,9 @@ public class MediaTransferFlvByFFmpeg extends MediaTransfer {
 	private boolean running = false; // 启动
 	private boolean enableLog = true;
 
-	private int hcSize, wcSize = 0;
-
 	// 记录当前
 	long currentTimeMillis = System.currentTimeMillis();
 
-	/**
-	 * 用于没有客户端时候的计时
-	 */
-	private int noClient = 0;
-
 	public MediaTransferFlvByFFmpeg(final String executable) {
 		command.add(executable);
 		buildCommand();
@@ -233,7 +211,7 @@ public class MediaTransferFlvByFFmpeg extends MediaTransfer {
 
 					byte[] buffer = new byte[1024];
 					int len = 0;
-					ByteArrayOutputStream bos = new ByteArrayOutputStream();
+//					ByteArrayOutputStream bos = new ByteArrayOutputStream();
 					while (running) {
 
 						len = input.read(buffer);

+ 9 - 38
src/main/java/com/zj/thread/MediaTransferFlvByJavacv.java

@@ -1,16 +1,13 @@
 package com.zj.thread;
 
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.util.Map.Entry;
-import java.util.concurrent.ConcurrentHashMap;
 
 import org.bytedeco.ffmpeg.avcodec.AVPacket;
 import org.bytedeco.ffmpeg.global.avcodec;
 import org.bytedeco.ffmpeg.global.avutil;
 import org.bytedeco.javacv.FFmpegFrameGrabber;
 import org.bytedeco.javacv.FFmpegFrameRecorder;
-import org.bytedeco.javacv.FFmpegLogCallback;
 import org.bytedeco.javacv.Frame;
 import org.bytedeco.javacv.FrameGrabber.Exception;
 
@@ -38,24 +35,12 @@ import lombok.extern.slf4j.Slf4j;
  * 转封装暂不支持hevc、vvc、vp8、vp9、g711、g771a等编码
  * </p>
  * <b> 转码累积延迟补偿暂未实现。</b> *
- * 由于转流过程中的拉流解码和编码是个线性串联链,多线程转码也不能解决该问题,后面可能需要采用主动跳包方式来解决 * * @author ZJ
- * * @author eguid
+ * 由于转流过程中的拉流解码和编码是个线性串联链,多线程转码也不能解决该问题,后面可能需要采用主动跳包方式来解决 
+ * @author ZJ
+ * @author eguid
  */
 @Slf4j
 public class MediaTransferFlvByJavacv extends MediaTransfer implements Runnable {
-	static {
-		avutil.av_log_set_level(avutil.AV_LOG_ERROR);
-		FFmpegLogCallback.set();
-	}
-
-	/**
-	 * ws客户端
-	 */
-	private ConcurrentHashMap<String, ChannelHandlerContext> wsClients = new ConcurrentHashMap<>();
-	/**
-	 * http客户端
-	 */
-	private ConcurrentHashMap<String, ChannelHandlerContext> httpClients = new ConcurrentHashMap<>();
 
 	/**
 	 * 运行状态
@@ -66,25 +51,8 @@ public class MediaTransferFlvByJavacv extends MediaTransfer implements Runnable
 
 	private boolean recorderStatus = false;
 
-	/**
-	 * 当前在线人数
-	 */
-	private int hcSize, wcSize = 0;
-
-	/**
-	 * 用于没有客户端时候的计时
-	 */
-	private int noClient = 0;
-
-	/**
-	 * flv header
-	 */
-	private byte[] header = null;
-	// 输出流,视频最终会输出到此
-	private ByteArrayOutputStream bos = new ByteArrayOutputStream();
-
-	FFmpegFrameGrabber grabber;// 拉流器
-	FFmpegFrameRecorder recorder;// 推流录制器
+	private FFmpegFrameGrabber grabber;// 拉流器
+	private FFmpegFrameRecorder recorder;// 推流录制器
 
 	/**
 	 * true:转复用,false:转码
@@ -275,10 +243,12 @@ public class MediaTransferFlvByJavacv extends MediaTransfer implements Runnable
 	 */
 	protected void transferStream2Flv() {
 		if (!createGrabber()) {
+			super.transferCallback.start(false);
 			return;
 		}
 		transferFlag = supportFlvFormatCodec();
 		if (!createTransterOrRecodeRecorder()) {
+			super.transferCallback.start(false);
 			return;
 		}
 
@@ -295,7 +265,8 @@ public class MediaTransferFlvByJavacv extends MediaTransfer implements Runnable
 		}
 
 		running = true;
-
+		
+		super.transferCallback.start(true);
 		// 启动监听线程(用于判断是否需要自动关闭推流)
 		listenClient();
 

+ 1 - 2
src/main/java/com/zj/thread/MediaTransferHls.java

@@ -10,7 +10,6 @@ import com.zj.common.MediaConstant;
 import com.zj.dto.CameraDto;
 
 import cn.hutool.core.collection.CollUtil;
-import cn.hutool.crypto.digest.MD5;
 import lombok.extern.slf4j.Slf4j;
 
 /**
@@ -74,7 +73,7 @@ public class MediaTransferHls extends MediaTransfer {
 		command.add("-g");
 		command.add("25");
 		command.add("-c:v");
-		command.add("h264");	//javacv 1.5.5 无法使用libx264
+		command.add("libopenh264");	//javacv 1.5.5 无法使用libx264
 		command.add("-c:a");
 		command.add("aac");
 		command.add("-f");

+ 11 - 0
src/main/java/com/zj/thread/TransferCallback.java

@@ -0,0 +1,11 @@
+package com.zj.thread;
+
+/**
+ * 转码回调
+ * @author ZJ
+ *
+ */
+public interface TransferCallback {
+
+	public void start(boolean startSuccess);
+}