天天看點

javacv-ffmpeg(二)圖檔截取

說明

支援本地檔案、rtmp、rtsp、http-flv、hls

一、視訊拉取

示範方法隻切圖一張,如果想隔幾秒切幾張圖 ,在if條件中加時間判斷就行了。

f.timestamp 可以擷取到該幀時間,機關微秒。

//方法或者外部類代碼在後邊
		FFmpegFrameGrabber ff = new FFmpegFrameGrabber(videofile);
		// 微秒 大概為設定時間的兩倍 
		ff.setOption(TimeoutOption.RW_TIMEOUT.getKey(), "10000000");
		// rtsp 預設udp 丢包 改為tcp
		ff.setOption("rtsp_transport", "tcp");
		ff.start();
		Frame f = null;
		while (true) {
			f = ff.grabFrame();
			if (null != f) {
				// 若顯示幀不為關鍵幀,則尋找相鄰的下一幀
				if (f.image != null) {
					doExecuteBase(f, timestamp);
					break;
				}
			}
		}

		ff.release();
		ff.stop();
           

二、TimeoutOption

/**
 * 流媒體逾時沒有通用選項。每個協定都有 自己的選項清單。
 */
public enum TimeoutOption {

	/**
	 * 取決于協定(FTP,HTTP,RTMP,SMB,SSH,TCP,UDP或UNIX)。
	 * 
	 * http://ffmpeg.org/ffmpeg-all.html
	 */
	TIMEOUT,
	/**
	 * 協定
	 *
	 * 等待(網絡)讀/寫操作完成的最長時間, 以微秒為機關。
	 *
	 * http://ffmpeg.org/ffmpeg-all.html#Protocols
	 */
	RW_TIMEOUT,
	/**
	 * Protocols -> RTSP
	 *
	 * 設定套接字TCP I / O逾時(以微秒為機關)。
	 *
	 * http://ffmpeg.org/ffmpeg-all.html#rtsp
	 */
	STIMEOUT;

	public String getKey() {
		return toString().toLowerCase();
	}

}
           

三、輸出成base64

/**
	 * 輸出成base64,儲存到資料結構
	 */
	public static void doExecuteBase(Frame f, String filename, long date) {
		if (null == f || null == f.image) {
			return;
		}

		Java2DFrameConverter converter = new Java2DFrameConverter();
		BufferedImage bi = converter.getBufferedImage(f);

		String base64 = getImageBinary(bi, "jpg");
	}

	/**
	 * 圖檔流轉化成base64
	 */
	public static String getImageBinary(BufferedImage bi, String format) {
		try {
			ByteArrayOutputStream baos = new ByteArrayOutputStream();// io流
			ImageIO.write(bi, format, baos);// 寫入流中
			byte[] bytes = baos.toByteArray();// 轉換成位元組
			BASE64Encoder encoder = new BASE64Encoder();
			String base64 = encoder.encodeBuffer(bytes).trim();// 轉換成base64串
			base64 = base64.replaceAll("\n", "").replaceAll("\r", "");// 删除 \r\n
			return base64;
		} catch (IOException e) {
			log.info("base64轉化失敗");
			e.printStackTrace();
		}
		return null;
	}
           

四、輸出成本地圖檔

/**
	 * 輸出成本地圖檔
	 */
	public static void doExecuteFrame(Frame f, String targetFileName) {
		if (null == f || null == f.image) {
			return;
		}
		Java2DFrameConverter converter = new Java2DFrameConverter();
		BufferedImage bi = converter.getBufferedImage(f);
		File output = new File(targetFileName);
		try {
			ImageIO.write(bi, "jpg", output);

		} catch (IOException e) {
			e.printStackTrace();
		}
	}