前言:

這個專案是之前在開發 Project 52 所開發出來的,原因是看到一些解析 youtube 影片資訊的內容。透過 Golang 的 channel 跟 goroutine 可以很快速的開發出來一個小工具。 專案完成後,其實也沒有特別維護他。想不到卻受到大家的喜愛,Star 數也破了兩百。

由於 Youtube 其實對於資料格式也有修改(截至 2019/12/10 當下) ,這裡也針對目前的資訊來探討如何透過 Golang 來抓取相關資訊,並且取得影片標題,作者姓名,甚至是取得下載鏈結的方式。

專案: github.com/kkdai/youtube

Github: https://github.com/kkdai/youtube

直接下載使用:
- go install github.com/kkdai/youtube/youtubedr

用法1: (另存檔名為 Campaign Diary.mp4)
youtubedr -o "Campaign Diary".mp4 https://www.youtube.com/watch\?v\=XbNghLqsVwU

用法2: (不指定檔名,而使用影片標題)
youtubedr https://www.youtube.com/watch\?v\=XbNghLqsVwU

這邊提供幾個簡單的操作方式,目前該套件只支援 mov (mpeg4) 的格式,如果需要另外轉檔 (mkv) 則需要透過 FFMPEG 跟其它套件的幫忙。這邊會放在之後支援的部分(issue #20) ,當然也歡迎各位的貢獻一起來幫忙。

抓取 Youtube 影片資訊

取得 Youtube 影片 ID 與取得資訊:

舉個例子 Rob Pike 在 dotGo 2015 裡面的一個很棒的 talk - Simplicity is Complicated ,該影片的位置如下:

https://www.youtube.com/watch?v=rFejpH_tAHM

這邊簡單的簡介一下,在 Youtube 每一則影片都有一個 ID,這個影片的 ID 則為 rFejpH_tAHM

如果需要取得影片的相關資訊,則需要呼叫

https://youtube.com/get_video_info?video_id={YOUR_VIDEO_ID}

來取得,也就是如果要取得這部影片的資訊需要鏈結到 https://youtube.com/get_video_info?video_id=rFejpH_tAHM

取得資訊與相關處理程式碼:

接下來依序討論如何尋找影片 title 與資料。首先來詳細查看剛剛取得的相關資料。

因為取得下來的是 URK-encoded query string 的資料,需要透過以下的處理方式。

首先,你需要處理一下錯誤訊息。由於許多的影片本身只有 MKV 的格式,或是禁止下載分享,如此一來在取得相關資訊的時候則會發生錯誤的 status ,這裡需要處理一下。

取得影片標題與影片作者資訊:

如果沒有錯誤訊息,接下來可以繼續處理相關資訊。 這裡得說一下,其實大多數的資料有修改過。跟網路上可以找得到的資訊不同。所以後來花了很多的時間重新搜尋相關資訊,並且整理與轉換。 透過上述的 parseVideoInfo 轉換後可以取的 url.Values 也就是變數名稱的 answer

處理上可以參考下列的方式,由於發現 ``answer[“player_response”]` 裡面有 Map 結構的資料格式,於是透過以下的方式可以取得相關資訊。

這邊有些比較少見的用法,稍微解釋一下。

if err := json.Unmarshal([]byte(playResponse[0]), &personMap); err != nil {
		panic(err)
	}

這個透過 JSON unmarshal 的方式來將JSON string 轉換成 map 。 轉換成 map 之後就可以尋找與取值,這裡可以使用 videoDetails

至於讀者可能會好奇這些資料格式是如何知道的,並且知道資料所在的位置。 這也是不斷地透過 iteration 來尋找才找到的。

取得 map 資料取出後,由於資料預設格式都會是 interface{} 如果要轉換成 string 輸出的話。可以透過 type assertion 或是直接轉換的方式。

下載影片:

最後~來講解一下所有的影片格式搜尋方式,還有如何找到最高解析度的影片。

首先影片的資訊都在 streamMap, ok := data["url_encoded_fmt_stream_map"]透過以下的切割方式可以把所有的 stream format 分割出來。

streamsList := strings.Split(streamMap[0], ",")

而裡面可以透過 streamQry["quality"] 來讀取資訊,透過以上的範例可以了解,通常第一個 stream 也就是解析度最高的影片。 而他的下載鏈結就在 streamQry["url"]裡面就可以取得。

透過 Parse stream list 之後,找到最高解析度的影片,也就可以開始下載影片了。

注意:

  1. 並非所有影片都可以下載,如果不提供分享的影片則無法下載。
  2. 如果原本來源不是 MPEG4 的 mov 影片,無法順利下載,需要 transcode 。

結論:

原本是使用者的建議,希望如果在抓取 MPEG4 的時候可以預設使用影片的標題,而不一定要抓取檔案的一定要輸入檔名。 這樣的追下去才發現資料格式有修改,在此也分享給各位如何搜尋相關的資料。

是說~~好久沒寫扣了。真的心血來潮又是寫到天快亮。 orz

Reference:


Buy Me A Coffee

Evan

Attitude is everything