視頻截取某一幀(Linux/Windows)

預備條件:首先在服務器上執行如下命令,安裝必要文件!

yum install libXv*
yum install libXv.so.1

pom文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.1.2.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.demo</groupId>
	<artifactId>javaCY</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>javaCY</name>
	<description>Demo project for Spring Boot</description>

	<properties>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
        <!--  視頻  -->
		<dependency>
			<groupId>org.bytedeco.javacpp-presets</groupId>
			<artifactId>ffmpeg</artifactId>
			<version>3.1.2-1.2</version>
			<classifier>linux-x86</classifier>
		</dependency>
		<dependency>
			<groupId>org.bytedeco</groupId>
			<artifactId>javacv</artifactId>
			<version>1.4.1</version>
		</dependency>

		<!-- https://mvnrepository.com/artifact/org.bytedeco.javacpp-presets/ffmpeg-platform -->
		<dependency>
			<groupId>org.bytedeco.javacpp-presets</groupId>
			<artifactId>ffmpeg-platform</artifactId>
			<version>3.4.2-1.4.1</version>
		</dependency>

		<dependency>
			<groupId>commons-io</groupId>
			<artifactId>commons-io</artifactId>
			<version>2.4</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

將application.properties改爲:

server.port=8889

然後代碼如下:

	@PostMapping(value = "/test5")
	public void run5(HttpServletResponse response, MultipartFile file, Integer z) throws Exception {
		// 創建臨時文件
		File tempFile = new File("src/" + file.getOriginalFilename() + "");
		FileUtils.copyInputStreamToFile(file.getInputStream(), tempFile);
		// videofile視頻路徑,這裏用的是臨時文件的路徑
		FFmpegFrameGrabber ff = new FFmpegFrameGrabber(tempFile);
		ff.start();
		//獲取幀長
		int lenght = ff.getLengthInFrames();
		int i = 0;
		Frame f = null;
		while (i < lenght) {
			// 過濾前z幀,避免出現全黑的圖片
			f = ff.grabFrame();
			if ((i > z) && (f.image != null)) {
				break;
			}
			i++;
		}
		int owidth = f.imageWidth;
		int oheight = f.imageHeight;
		// 對截取的幀進行等比例縮放
		int width = 800;
		int height = (int) (((double) width / owidth) * oheight);
		//創建Java2DFrameConverter用於在幀和BufferedImage之間複製數據
		Java2DFrameConverter converter = new Java2DFrameConverter();
		BufferedImage tempImage = converter.getBufferedImage(f);
		BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
		image.getGraphics().drawImage(tempImage.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0, 0, null);
		ImageIO.write(image, "jpg", response.getOutputStream());
		response.getOutputStream().close();
		ff.stop();
		if (tempFile.exists() && tempFile.isFile()) {
			if (tempFile.delete()) {
				System.out.println("刪除臨時文件" + tempFile + "成功!");
			}
		}
	}

最後執行mvn clean install打包後上傳到服務器:

ok~服務器上傳視頻截幀就行了,需要注意的是在windows環境下會報錯因爲我選擇的linux版本:

所以在本地測試時需要把<classifier>linux-x86</classifier>刪除。

下面再來個demo,拿取一個視頻所有幀並保存:

	@PostMapping(value = "/test5")
	public void run5(MultipartFile file) throws Exception {
		// 創建臨時文件
		File tempFile = new File("src/" + file.getOriginalFilename() + "");
		FileUtils.copyInputStreamToFile(file.getInputStream(), tempFile);
		// videofile視頻路徑,這裏用的是臨時文件的路徑
		FFmpegFrameGrabber ff = new FFmpegFrameGrabber(tempFile);
		ff.start();
		// 獲取幀長
		int lenght = ff.getLengthInFrames();
		int i = 0;
		Frame f = null;
		while (i < lenght) {
			// 過濾前z幀,避免出現全黑的圖片
			f = ff.grabFrame();
			if ((f.image != null)) {
				int owidth = f.imageWidth;
				int oheight = f.imageHeight;
				// 對截取的幀進行等比例縮放
				int width = 800;
				int height = (int) (((double) width / owidth) * oheight);
				// 創建Java2DFrameConverter用於在幀和BufferedImage之間複製數據
				Java2DFrameConverter converter = new Java2DFrameConverter();
				BufferedImage tempImage = converter.getBufferedImage(f);
				BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
				image.getGraphics().drawImage(tempImage.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0, 0,
						null);
				File jpgFile = new File("D:\\new\\"+file.getName()+""+i+".jpg");
				//如果目錄不存在則創建
				if (!jpgFile.getParentFile().exists()) {
				    try {
				    	jpgFile.getParentFile().mkdirs();
				    	jpgFile.createNewFile();
				    } catch (IOException e) {
				        e.printStackTrace();
				    }
				}
				ImageIO.write(image, "jpg", jpgFile);
			}
			i++;
		}
		ff.stop();
	}

Ok~nice~~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章