下午好,Khabravchians! 针对初学者的文章,这里不会出现某些新想法。 而且此功能很可能以多种语言实现了数十次。 想法是,如果您获得Twitter上包含视频的帖子的链接,请拾取该视频并将其转换为mkv。
为了生意!
我们需要什么:
- 去吧
- ffmpeg
- 泊坞窗(尽管没有它也是可能的。但是,这些天在哪里没有它?!;)
我们有一个来自视频的推文的链接:
https://twitter.com/FunnyVines/status/1101196533830041600
在整个链接中,我们只对由数字组成的ID感兴趣,因此我们以基本的规律性提取了整个数字子串:
var reurl = regexp.MustCompile(`\/(\d*)$`)
使用收到的ID,转到地址:
resp, err := client.Get("https://twitter.com/i/videos/tweet/" + id)
我们从哪里获得指向视频播放器JS代码的链接:
src="https://abs.twimg.com/web-video-player/TwitterVideoPlayerIframe.f52b5b572446290e.js"
从这个js文件中,我们需要一件非常重要的事情-twitter api中的授权承载。
Regex'pee他!
re, _ := regexp.Compile(`(?m)authorization:\"Bearer (.*)\",\"x-csrf`)
这还不足以访问api,您仍然需要guest_token。 可以通过将POST请求应用于地址“ https://api.twitter.com/1.1/guest/activate.json ”,并在其中传递:cookie中的personalization_id和guest_id(我们在访问上一个请求时在服务器的响应中收到的)来获得该请求网址):
var personalization_id, guest_id string cookies := resp.Cookies() for _, cookie := range cookies { if cookie.Name == "personalization_id" { personalization_id = cookie.Value } if cookie.Name == "guest_id" { guest_id = cookie.Value } }
guest_token它是定期更改的,我不知道调用它的频率(而是,它在计时器中更改-15分钟的间隔),但是似乎定期激活/1.1/guest/activate.json可以让您绕过300个请求的api限制。
答案是gzip,可以在Go中解压缩,如下所示:
res, err := gzip.NewReader(resp.Body) if err != nil { return "", err } defer res.Close() r, err := ioutil.ReadAll(res)
好吧,就是这样! 现在,我们拥有调用API所需的一切:
url, _ = url.Parse("https://api.twitter.com/1.1/videos/tweet/config/" + id + ".json") request = &http.Request{ Method: "GET", URL: url, Header: http.Header{ "user-agent": []string{"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"}, "accept-encoding": []string{"gzip", "deflate", "br"}, "origin": []string{"https://twitter.com"}, "x-guest-token": []string{gt.GuestToken}, "referer": []string{"https://twitter.com/i/videos/tweet/" + id}, "authorization": []string{"Bearer " + bearer}}, } resp, err = client.Do(request)
API的响应将是Json,其中包含视频的描述,最重要的是,接收该视频的URL(playbackUrl):
{"contentType":"media_entity","publisherId":"4888096512","contentId":"1096941371649347584","durationMs":11201,"playbackUrl":"https:\/\/video.twimg.com\/ext_tw_video\/1096941371649347584\/pu\/pl\/xcBvPmwAmKckck-F.m3u8?tag=6","playbackType"
最后,我们有了视频地址,将其发送给ffmpeg,同时检查了哪种视频格式,我看到了2种可能的格式,第一种是mp4:
if strings.Contains(videoURL.Track.PlaybackURL, ".mp4") { convert := exec.Command("ffmpeg", "-i", videoURL.Track.PlaybackURL, "-c", "copy", "./videos/"+id+".mkv") convert.Stdout = os.Stdout convert.Stderr = os.Stderr if convert.Run() != nil { return "", err } return id, nil }
第二个是m3u8播放列表文件,对于此选项, 还需要再执行一步-我们得到GET
他,然后以所需的分辨率获取内容的URL:
#EXT-X-INDEPENDENT-SEGMENTS #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=256000,RESOLUTION=180x316,CODECS="mp4a.40.2,avc1.4d0015" /ext_tw_video/1039516210948333568/pu/pl/180x316/x0HWMgnbSJ9y6NFL.m3u8 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=832000,RESOLUTION=464x816,CODECS="mp4a.40.2,avc1.4d001f" /ext_tw_video/1039516210948333568/pu/pl/464x816/Z58__ptq1xBk8CIV.m3u8
而且-ffmpeg。
现在,有关HTTP服务器的一些知识
我用过:
逻辑如下,我们启动服务器:
cfg := tcplisten.Config{ ReusePort: true, FastOpen: true, DeferAccept: true, Backlog: 1024, } ln, err := cfg.NewListener("tcp4", ":8080") if err != nil { log.Fatalf("error in reuseport listener: %s\n", err) } serv := fasthttp.Server{Handler: e.Handler, ReduceMemoryUsage: false, Name: "highload", Concurrency: 2 * 1024, DisableHeaderNamesNormalizing: true} if err := serv.Serve(ln); err != nil { log.Fatalf("error in fasthttp Server: %s", err) }
而且我们只处理一条路线/ *视频:
如何收集所有这些?
例如,一个简单的Makefile(make build,make run ...):
build: go build -o main docker build -t tvideo . run: go build -o main docker build -t tvideo . docker kill tvideo docker run -d --rm --name tvideo -v /etc/ssl:/etc/ssl:ro -v videos:/opt/videos -p 8080:8080 tvideo docker logs -f tvideo
请注意标志“ -v / etc / ssl:/ etc / ssl:ro”,在基本映像ubuntu中没有根证书,并且http客户端无法识别https twitter,通过--volume将它从主机扔掉(现在,就像如何使用--mount更正确。
Docker文件
FROM ubuntu // docker image COPY main /opt/app RUN apt-get update && \ // apt-get install -y ffmpeg && \ chmod +x /opt/app EXPOSE 8080 WORKDIR /opt CMD ./app
无疑,我在这篇文章中没有发现美国,但是突然之间,它将对某些人派上用场。
资料来源在这里 。