[FFmpeg] java realizes using ffmpeg video upload and transcoding while intercepting a frame and saving it as a picture of the same name, and obtaining the video resolution (supplementary part)

antecedent summary

After completing the video upload, the next step is to save a jpg file with the same name for the uploaded video in the same folder, and obtain the resolution of the video.
But I encountered all kinds of headaches on the way to get the resolution...
macOS Catalina 10.15.1
ffmpeg version 4.3.1
Eclipse

refer to:

  1. [FFmpeg] Install FFmpeg on the mac system and transcode the video, take screenshots of the video, and compress the video
    https://blog.csdn.net/weixin_43210113/article/details/109802138
  2. [FFmpeg] java realizes the use of ffmpeg video upload and transcoding while intercepting a frame and saving it as a picture of the same name, and obtaining the video resolution
    https://blog.csdn.net/weixin_43210113/article/details/109807300
  3. java split string Unclosed character class near index error
    https://blog.csdn.net/u014608640/article/details/80020032
  4. java extract numbers from string
    https://www.cnblogs.com/lxqiaoyixuan/p/8541530.html

1. Problem description

When uploading, I encountered different video information descriptions.
There are three types after the summary, but there may be more, comments are welcome...but the final solution should be unshakable...
If you don't want to see the first failure analysis, please directly read the second analysis of part 3.

2. The first analysis

refer to

Last time I talked about using this big guy's method.

refer to:
Simple and rude: Java uses FFmpeg to get the resolution of the video Java gets the duration of the video Java gets the encoding format of the video
https://blog.csdn.net/q2450751976/article/details/103993096

Directly take the line at the beginning of the Stream where the fps is found, and it can be split into

Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661),
 yuv420p(tv,
 bt709),
 1920x1080 [SAR 1:1 DAR 16:9],
 3779 kb/s,
 30 fps,
 30 tbr,
 90k tbn,
 180k tbc (default)

where [3] is the desired 1920x1080 [SAR 1:1 DAR 16:9],

definition = definition.trim().split(" ")[0];
Remove the leading and trailing spaces through trim(), and then split .split(" ")[] through spaces to get

 1920x1080 
 [SAR 
 1:1
 DAR
 16:9],

Take [0] to get the resolution

my original

For detailed explanation, please go to

My article:
[FFmpeg] java realizes the use of ffmpeg video upload and transcoding while intercepting a frame and saving it as a picture of the same name, and obtaining the video resolution
https://blog.csdn.net/weixin_43210113/article/details/109807300

problem finding

✨Note: The information output by each video is not the same, you need to change the way to get it

first try

Video1: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709), 1920x1080 [SAR 1:1 DAR 16:9],

✨Video2: h264 (High) (avc1 / 0x31637661), yuv420p, 640x360 [SAR 1:1 DAR 16:9], 1201 kb

Video1 has one more (tv, bt709) after yuv420p.
So according to, the segmentation will encounter problems, change to [split try.
Later, the existence of video4 was discovered, but [] did not exist, and the video was downloaded from the Internet...
I've served it, then divide it by the second x and then take it left and right... If there is any problem with the video, I'll... change it again.

		String definition = null;
		String line = "Video1: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709), 1920x1080 [SAR 1:1 DAR 16:9]";
		//String line = "Video2: h264 (High) (avc1 / 0x31637661), yuv420p, 640x360 [SAR 1:1 DAR 16:9], 1201 kb";
		definition = line.split("\\[")[0];
		String[] find = definition.trim().split(" ");
		String pix = find[find.length-1];

Note: Direct segmentation ("[") will have Unclosed character class near index error

refer to:
java split string Unclosed character class near index error
https://blog.csdn.net/u014608640/article/details/80020032

| . * [] \ are special characters that need to be escaped when used

into my FFmpegTest.java

// Video resolution
    public static String videoInfo(String media_rand_name){
    	String path = "video path prefix";
    	String ffmpegPath = "ffmpeg path";
    	
        String inputVideoPath = path + media_rand_name + ".mp4";

        StringBuffer buffer = new StringBuffer();
        buffer.append(ffmpegPath);
        //Be careful to keep spaces between words
        buffer.append(" -i ");
        buffer.append(inputVideoPath);
        String definition = null;
        String pix = null;
		//Execute the command statement and return the execution result
        try {
            Process process = Runtime.getRuntime().exec(buffer.toString());
            InputStream in = process.getErrorStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(in));
            String line ;
            while((line=br.readLine())!=null) {
                //Generally, the line containing the fps contains the resolution
                if(line.contains("fps")){
                    //Remove leading and trailing spaces according to [ split trim
                    definition = line.split("\\[")[0];
                    String[] find = definition.trim().split(" ");
                    pix = find[find.length-1];
                    System.out.println(pix);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
		return pix;
    }

test

Successfully stored in the database (with the need to modify the content in the servlet)

3. The second attempt

I thought I would be very happy, but found out that the video downloaded from the good-looking video does not have []

Video1: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709), 1920x1080 [SAR 1:1 DAR 16:9],

✨Video2: h264 (High) (avc1 / 0x31637661), yuv420p, 640x360 [SAR 1:1 DAR 16:9], 1201 kb

✨Video3: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709), 1280x720, 399 kb/s, 24.98 fps, 25 tbr, 12800 tbn, 50 tbc (default)

Analysis of the law

How else can I dismantle... use x to dismantle

h264 (High) (avc1 / 0
31637661), yuv420p(tv, bt709), 1280
720, 399 kb/s, 24.98 fps, 25 tbr, 12800 tbn, 50 tbc (default)

Then take the split [len-1] in [1]
Take in [2], and divide the digital part in [0] ([0] may have ,)
connect with x

get number in string

regular expression

refer to
java extract numbers from string
https://www.cnblogs.com/lxqiaoyixuan/p/8541530.html

public static void main(String[] args) {
String a="love23next234csdn3423javaeye";
String regEx="[^0-9]";  
Pattern p = Pattern.compile(regEx);  
Matcher m = p.matcher(a);  
System.out.println( m.replaceAll("").trim());
}

java test

public static void main(String[] args) {
		String Video = " h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709), 1280x720, 399 kb/s, 24.98 fps, 25 tbr, 12800 tbn, 50 tbc (default)";
		
		String definition1 = null;
		String definition2 = null;
		String pix = null;
        //Remove leading and trailing spaces according to [ split trim
		definition1 = Video.split("x")[1];
        definition2 = Video.split("x")[2];
        String[] find1 = definition1.trim().split(" ");
        String find2 = definition2.trim().split(" ")[0];
        pix = find1[find1.length-1]+"x"+findNum(find2);
        
        System.out.println(pix);

	}
	
	// find number in string
	public static String findNum(String find2) {
		String a=find2;
		String regEx="[^0-9]";  
		Pattern p = Pattern.compile(regEx);  
		Matcher m = p.matcher(a);  
		System.out.println( m.replaceAll("").trim());
		return m.replaceAll("").trim();
		}

There will be no such thing,

into my FFmpegTest.java

// Video resolution
    public static String videoInfo(String media_rand_name){
    	String path = "video path prefix";
    	String ffmpegPath = "ffmpeg path";
    	
        String inputVideoPath = path + media_rand_name + ".mp4";

        StringBuffer buffer = new StringBuffer();
        buffer.append(ffmpegPath);
        //Be careful to keep spaces between words
        buffer.append(" -i ");
        buffer.append(inputVideoPath);
        String definition = null;
        String definition1,definition2,pix = null;
		//Execute the command statement and return the execution result
        try {
            Process process = Runtime.getRuntime().exec(buffer.toString());
            InputStream in = process.getErrorStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(in));
            String line ;
            while((line=br.readLine())!=null) {
                //Generally, the line containing the fps contains the resolution
                if(line.contains("fps")){
                    //Split trim according to x to delete leading and trailing spaces
                	definition1 = line.split("x")[1];
                    definition2 = line.split("x")[2];
                    String[] find1 = definition1.trim().split(" ");
                    String find2 = definition2.trim().split(" ")[0];
                    pix = find1[find1.length-1]+"x"+findNum(find2);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
		return pix;
    }

If there is a problem, continue to study

Tags: Java ffmpeg

Posted by Hipster on Fri, 29 Jul 2022 02:35:37 +0930