Goのanacondaで140秒動画ツイート
18220 ワード
はじめに
以前Goで動画つきツイートをするtwittebotを書きましたが,その際は5MB以下のみのツイートでした.
今回は140秒動画をanacondaを使用します.
現在(2018/4/15),140秒動画に対応するメソッドがないため,自作してそれを使用したいと思います.
twiiter APIに沿ったメソッドの作成
twitter API Documentationを参考に
anacondaのmedia.goに以下を追記します.
media.go
....
func (a TwitterApi) UploadVideoInit(totalBytes int, mimeType string) (chunkedMedia ChunkedMedia, err error) {
v := url.Values{}
v.Set("command", "INIT")
v.Set("media_type", mimeType)
v.Set("total_bytes", strconv.FormatInt(int64(totalBytes), 10))
//追加
v.Set("media_category", "tweet_video")
var mediaResponse ChunkedMedia
response_ch := make(chan response)
a.queryQueue <- query{UploadBaseUrl + "/media/upload.json", v, &mediaResponse, _POST, response_ch}
return mediaResponse, (<-response_ch).err
}
....
//以下を全て追加
type StatusMedia struct {
MediaID int64 `json:"media_id"`
MediaIDString string `json:"media_id_string"`
MediaKey string `json:"media_key"`
ExpiresAfterSecs int `json:"expires_after_secs"`
ProcessingInfo struct {
State string `json:"state"`
CheckAfterSecs int `json:"check_after_secs"`
ProgressPercent int `json:"progress_percent"`
} `json:"processing_info"`
}
func (a TwitterApi) UploadVideoStatus(mediaIdString string) (videoMedia StatusMedia, err error) {
v := url.Values{}
v.Set("command", "STATUS")
v.Set("media_id", mediaIdString)
var mediaResponse StatusMedia
response_ch := make(chan response)
a.queryQueue <- query{UploadBaseUrl + "/media/upload.json", v, &mediaResponse, _GET, response_ch}
return mediaResponse, (<-response_ch).err
}
これで完成です.
上記のメソッドを使用して動画をtweetする
main.go
package main
import (
"encoding/base64"
"io/ioutil"
"net/url"
"os"
"github.com/ChimeraCoder/anaconda"
)
func main() {
anaconda.SetConsumerKey(os.Getenv("CONSUMER_KEY"))
anaconda.SetConsumerSecret(os.Getenv("CONSUMER_SECRET"))
api := anaconda.NewTwitterApi(os.Getenv("ACCESS_TOKEN"), os.Getenv("ACCESS_TOKEN_SECRET"))
file, err := os.Open("ex.mp4")
if err != nil {
panic(err)
}
defer file.Close()
byteMedia, err := ioutil.ReadAll(file)
if err != nil {
panic(err)
}
fileStatus, err := file.Stat()
if err != nil {
panic(err)
}
size := int(fileStatus.Size())
chunkMedia, err := api.UploadVideoInit(size, "video/mp4")
if err != nil {
panic(err)
}
//The base64-encoded chunk of media file. It must be <= 5 MB
chunkSize := 5 * 1024 * 1024
index := 0
for i := 0; i < size; i += chunkSize {
var data string
if (size-i)/chunkSize > 0 {
data = base64.StdEncoding.EncodeToString(byteMedia[i : i+chunkSize])
} else {
data = base64.StdEncoding.EncodeToString(byteMedia[i:])
}
if err = api.UploadVideoAppend(chunkMedia.MediaIDString, index, data); err != nil {
panic(err)
}
index++
}
video, err := api.UploadVideoFinalize(chunkMedia.MediaIDString)
if err != nil {
panic(err)
}
for {
videos, err := api.UploadVideoStatus(chunkMedia.MediaIDString)
if err != nil {
panic(err)
}
if videos.ProcessingInfo.State == "succeeded" {
break
}
time.Sleep(time.Duration(videos.ProcessingInfo.CheckAfterSecs))
}
params := url.Values{}
params.Add("media_ids", video.MediaIDString)
if _, err := api.PostTweet("text", params); err != nil {
panic(err)
}
}
肝は5MB以下でしか送信できないため,チャンクに分けて送信しなければいけないところです.
そして送信毎にCheckAfterSecs
がレスポンスで返ってくるので,その時間だけsleepしProcessingInfo.State
がsucceeded
になるまで待つ処理が必要です.
これでtweetできます.
最後に
これをもう少し綺麗に整えてPRを出そうとしたのですが,現在(2018/4/15),140秒動画に対応するメソッドがPRに既にありました笑
初めてのOSSにコミットしてみたかったーーーー!
終わり
Author And Source
この問題について(Goのanacondaで140秒動画ツイート), 我々は、より多くの情報をここで見つけました https://qiita.com/Ryoma0413/items/08fb6e5dd7d1fbd5026a著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .