135 lines
3.1 KiB
Go
Raw Normal View History

2020-02-08 20:44:46 +08:00
package twitter
import (
"encoding/json"
"fmt"
"strconv"
"strings"
"github.com/iawia002/annie/downloader"
"github.com/iawia002/annie/extractors"
"github.com/iawia002/annie/request"
"github.com/iawia002/annie/utils"
)
type twitter struct {
Track struct {
URL string `json:"playbackUrl"`
} `json:"track"`
TweetID string
Username string
}
// Extract is the main function for extracting data
func Extract(uri string) ([]downloader.Data, error) {
html, err := request.Get(uri, uri, nil)
if err != nil {
return nil, err
}
usernames := utils.MatchOneOf(html, `property="og:title"\s+content="(.+)"`)
if usernames == nil || len(usernames) < 2 {
return nil, extractors.ErrURLParseFailed
}
username := usernames[1]
tweetIDs := utils.MatchOneOf(uri, `(status|statuses)/(\d+)`)
if tweetIDs == nil || len(tweetIDs) < 3 {
return nil, extractors.ErrURLParseFailed
}
tweetID := tweetIDs[2]
api := fmt.Sprintf(
"https://api.twitter.com/1.1/videos/tweet/config/%s.json", tweetID,
)
headers := map[string]string{
"Authorization": "Bearer AAAAAAAAAAAAAAAAAAAAAIK1zgAAAAAA2tUWuhGZ2JceoId5GwYWU5GspY4%3DUq7gzFoCZs1QfwGoVdvSac3IniczZEYXIcDyumCauIXpcAPorE",
}
jsonString, err := request.Get(api, uri, headers)
if err != nil {
return nil, err
}
var twitterData twitter
if err := json.Unmarshal([]byte(jsonString), &twitterData); err != nil {
return nil, extractors.ErrURLParseFailed
}
twitterData.TweetID = tweetID
twitterData.Username = username
extractedData, err := download(twitterData, uri)
if err != nil {
return nil, err
}
return extractedData, nil
}
func download(data twitter, uri string) ([]downloader.Data, error) {
var (
err error
size int64
)
streams := make(map[string]downloader.Stream)
switch {
// if video file is m3u8 and ts
case strings.Contains(data.Track.URL, ".m3u8"):
m3u8urls, err := utils.M3u8URLs(data.Track.URL)
if err != nil {
return nil, err
}
for index, m3u8 := range m3u8urls {
var totalSize int64
var urls []downloader.URL
ts, err := utils.M3u8URLs(m3u8)
if err != nil {
return nil, err
}
for _, i := range ts {
size, err := request.Size(i, uri)
if err != nil {
return nil, err
}
temp := downloader.URL{
URL: i,
Size: size,
Ext: "ts",
}
totalSize += size
urls = append(urls, temp)
}
qualityString := utils.MatchOneOf(m3u8, `/(\d+x\d+)/`)[1]
quality := strconv.Itoa(index + 1)
streams[quality] = downloader.Stream{
Quality: qualityString,
URLs: urls,
Size: totalSize,
}
}
// if video file is mp4
case strings.Contains(data.Track.URL, ".mp4"):
size, err = request.Size(data.Track.URL, uri)
if err != nil {
return nil, err
}
urlData := downloader.URL{
URL: data.Track.URL,
Size: size,
Ext: "mp4",
}
streams["default"] = downloader.Stream{
URLs: []downloader.URL{urlData},
Size: size,
}
}
return []downloader.Data{
{
Site: "Twitter twitter.com",
Title: fmt.Sprintf("%s %s", data.Username, data.TweetID),
Type: "video",
Streams: streams,
URL: uri,
},
}, nil
}