I. Introduction
Hello everyone, as the saying goes, after learning new knowledge, you must apply what you have learned. In the process of learning audio and video, do you have any questions or do not know what audio and video can be used for. Here are a few examples. Some of the scenes that are familiar and blown to the tuyere are: AI visual computing, AI face recognition. Refined to some small areas, such as current live broadcast technology, camera monitoring and streaming; others include Douyin Behind the beauty and filters in China is the digital makeup technology used in the audio and video fields. This shows that the application of audio and video technology has been applied to all aspects of our lives.
2. Development background
The purpose of writing this article is because I have a friend who likes to use Tik Tok, and often some videos are set to be undownloadable and saved by the author. If the friend wants to watch it next time, he won’t be able to find it. There are also friends who want to download the works of the sister paper of the crush. So I told me the distress. As a friend, of course I have an obligation to help him out of the predicament. Finally, today, Two thousand years later, this gadget finally came out. Because of time, it is too late to write the front-end page. Students who need it later can do it. Follow or send a private letter to me. Let’s study together. In addition, the purpose of writing this article is purely learning. I.
Three, the core idea
In fact, the core steps are two steps
1. Obtain the real address of Douyin according to the shared link copied on Douyin, and you need to use network programming technology to resolve the real address of the video.
2. Then use ffmpeg to decode the network video stream and save it locally.
Fourth, the main technical points
1. Mainly use Java and some knowledge of network calls, such as the use of Restemplate. Restemplate is a template method class in spring web. Two of his methods (headForHeaders, exchange) are mainly used here. Of course, other tools can also be used. Class or implement remote network calls by yourself.
2. Fastjson is used for JSON parsing, and the version number is arbitrary, generally compatible.
3. StringUtils uses the tools in the commons.lang3 package. Don't lead the wrong package.
4. The third-party dependency used by ffmpeg to pull the stream is javacv, version 1.4.3. If you need a specific reference to rely on, follow or send a private message to me.
5. If you are not very clear about the basic concepts of ffmpeg, the basic concepts of audio and video, such as video frame, audio frame, bit rate and other basic knowledge, I will only talk about the application of technology here. Search a lot, if you are interested, you can learn about the following by yourself.
6. Use the FFmpegFrameGrabber frame grabber in javacv to obtain audio/video frames. With this grabber, you can omit a bunch of complex operations called by the native API, such as opening the video stream, searching for decoders, and judging audio frames and videos. frame.
An introduction/summary from the Internet
FFmpegFrameGrabber is used to capture/grab video images and audio samples. Encapsulates specific APIs such as retrieving stream information, automatically guessing video decoding format, audio and video decoding, and saving decoded pixel data (configurable pixel format) or audio data to Frame and returning.
7. You can also use the ffmpeg command line to download. The command is as follows:
ffmpeg -i https://xxx.mp4 -c copy -f flv 艾北.flv
But this method requires the deployment machine to install ffmpeg, so this method is not considered for the time being.
8. Use the FrameRecorder recorder in javacv to encode the decoded image pixels into the corresponding encoding and format and push it out. Here, saving it locally means pushing it to a local file.
The following is a summary of the introduction of FrameRecorder by eguid
FrameRecorder is used for audio/video/picture encapsulation, encoding, streaming, recording and saving operations. Take out the data in the Frame obtained from FrameGrabber or FrameFilter and perform operations such as encoding, encapsulation, and streaming. In order to facilitate understanding and reading, we will refer to FrameRecorder as the recorder from the beginning.
Five, detailed ideas
1. Link resolution & interface resolution
(1), Java regular expression extracts the url from the string.
(2) Use the RestTemplate.headForHeaders() method to obtain the request header information of a certain resource URI, and only focus on obtaining the HTTP request header information.
(3) The url extracted in the first step can be found by simulation in the browser, it will be redirected to a new address, and the redirected address is obtained from the request header, that is, the location is obtained from the header, and then from the location Get the real id of the video in.
(4). Obtain video information, such as playback information, author information, background music information, etc., according to the video's real id and Douyin's interface, and use json to parse out the url of the playback address layer by layer.
2. ffmpeg pulls the stream and saves
(1) Use ffmpeg to get the first frame of the url video frame, and check whether the video is an empty video.
(2) Create a video stream recorder, set video parameters, resolution, format, and output location.
(3) Obtain video frames cyclically, and use recorder to record video frames frame by frame.
Six, the core code
1. Use regular to extract url
/**
* 正则表达式提取 url
* @param text
* @return
*/
public static String pickURI(String text) {
// eg: text = "5.1 GV:/ 一出场就给人一种江南的感觉%刘亦菲 %精彩片段 %歌曲红马 https://v.douyin.com/e614JkV/ 腹制佌lian接,打开Dou音搜索,直接观kan视頻!";
Pattern pattern = Pattern.compile("https?://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]");
Matcher matcher = pattern.matcher(text);
if (matcher.find()) {
return matcher.group();
}
return "";
}
2. Initiate a network call and parse json to obtain the real address
public final static String DOU_YIN_WEB_API = "https://www.iesdouyin.com/web/api/v2/aweme/iteminfo/?item_ids=";
/**
* 根据赋值的分享码下载抖音视频
* @param text
* @throws FrameGrabber.Exception
* @throws FrameRecorder.Exception
*/
public static String douYin(String text) throws FrameGrabber.Exception, FrameRecorder.Exception {
//
String url = pickURI(text);
RestTemplate client = new RestTemplate();
//
HttpHeaders headers = client.headForHeaders(url);
String location = headers.getLocation().toString();
String vid = StringUtils.substringBetween(location, "/video/", "/?");
RestTemplate restTemplate = new RestTemplate();
HttpHeaders queryHeaders = new HttpHeaders();
queryHeaders.set(HttpHeaders.USER_AGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36");
HttpEntity<String> entity = new HttpEntity<>(queryHeaders);
ResponseEntity<JSONObject> response = restTemplate.exchange(DOU_YIN_WEB_API + vid, HttpMethod.GET, entity, JSONObject.class);
if(response.getStatusCodeValue() != 200) {
return "";
}
JSONObject body = response.getBody();
assert body != null;
List<JSONObject> list = JSONArray.parseObject(body.getJSONArray("item_list").toJSONString(), new TypeReference<List<JSONObject>>(){});
if(list.size() == 0) {
return "";
}
JSONObject item = list.get(0);
JSONObject video = item.getJSONObject("video");
JSONObject playAddr = video.getJSONObject("play_addr");
JSONArray urlList = playAddr.getJSONArray("url_list");
List<String> urlListArr = JSONArray.parseObject(urlList.toJSONString(), new TypeReference<List<String>>(){});
if(urlListArr.size() == 0) {
return "";
}
return urlListArr.get(0);
// VideoConvert.record(finalAddr, "/home/yinyue/upload/红马.flv");
}
3. ffmpeg pulls the stream and saves
/**
* 转存视频流
* @param input
* @param outFile
* @throws FrameGrabber.Exception
* @throws FrameRecorder.Exception
*/
public static void record(String input, String outFile) throws FrameGrabber.Exception, FrameRecorder.Exception {
FrameGrabber grabber = new FFmpegFrameGrabber(input);
grabber.start();
OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage();
Frame frame = grabber.grab();
opencv_core.IplImage image = null;
if(frame == null) {
System.out.println("第一帧为空,请检查视频源");
return;
}
image = converter.convert(frame);
FrameRecorder recorder = FrameRecorder.createDefault(outFile, frame.imageWidth, frame.imageHeight);
recorder.setVideoCodec(AV_CODEC_ID_H264);
recorder.setFormat("flv");
recorder.setFrameRate(25);
recorder.setGopSize(25);
recorder.start();
Frame saveFrame;
while((frame = grabber.grab()) != null) {
saveFrame = converter.convert(image);
// 获取类型, 视频或者音频
// EnumSet<Frame.Type> videoOrAudio = saveFrame.getTypes();
// 录制视频
recorder.record(saveFrame);
}
recorder.close();
}
Seven, run screenshots
After the operation is completed, the downloaded video file is successfully generated locally
8. The author's experience
We were born in an era where technology is flourishing and technology is changing with each passing day. Born in this era is both lucky and sad. In such a vast and endless wave of knowledge changes, it is difficult to guarantee omnipotence and perfection; some people focus on algorithms, some people focus on algorithms. With data processing, some people are not good at hands-on skills, but have very strong theoretical skills. For example, the famous physicist Yang Zhenning. Some people focus on how to apply the technology and are committed to applying technology to social life. So, if this article is useful to you Please feel free to appreciate it. If you feel that the content is too shallow or makes you feel uncomfortable, please stay silent and keep each other decent.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。