@@ -8,11 +8,11 @@ package api
8
8
9
9
import (
10
10
"bytes"
11
- "encoding/json"
12
11
"errors"
13
12
"fmt"
14
13
"io/ioutil"
15
14
"net/http"
15
+ "net/url"
16
16
"os"
17
17
"strings"
18
18
@@ -85,7 +85,8 @@ func videosListById(service *youtube.Service, part string, id string) {
85
85
//Gets Video Data from Youtube URL
86
86
func APIGetVideoStream (service youtube.Service , url string )(videoData []byte , err error ) {
87
87
88
- videoStream := new (RawVideoData )
88
+ video := new (RawVideoData )//raw video data
89
+ var decodedVideo []string //decoded video data
89
90
90
91
//Gets video Id
91
92
id , err := getVideoId (url )
@@ -98,130 +99,71 @@ func APIGetVideoStream(service youtube.Service, url string)(videoData []byte, er
98
99
defer resp .Body .Close ()
99
100
out , e := ioutil .ReadAll (resp .Body )
100
101
auth .HandleError (e , "Error reading video data" )
101
- if err = json .Unmarshal (out , & a .output ); err != nil {
102
- logrus .Errorf ("Error JSON Unmarshall: %v" , err )
102
+
103
+ output , er := url .ParseQuery (out )
104
+ if e != nil {
105
+ logrus .Fatalf ("Error Parsing video byte stream" , e )
103
106
}
104
- //Extract Video information.
105
- videoInfo := videosListById (service , "snippet,contentDetails" , id )//fileDetails part not permitted.
107
+ //fmt.Println(string(output))
108
+
109
+ //Process Video stream
110
+ video .URLEncodedFmtStreamMap = output ["url_encoded_fmt_stream_map" ]
111
+ video .Author = output ["author" ]
112
+ video .Title = output ["title" ]
113
+ video .Status = output ["status" ]
106
114
107
- //Get Data stream from video response
108
- if err = json .Unmarshal (out , & videoStream ); err != nil {
109
- logrus .Errorf ("Error JSON Unmarshall: %v" , err )
115
+ //Decode Video
116
+ outputStreams := strings .Split (video .URLEncodedFmtStreamMap [0 ], "," )
117
+ for cur , raw_data := range outputStream {
118
+ //decoding raw data stream
119
+ dec_data , err := url .ParseQuery (raw_data )
120
+ if err != nil {
121
+ logrus .Errorf ("Error Decoding Video data: %d, %v" , cur , err )
122
+ continue
123
+ }
124
+
125
+ data := map [string ]string {
126
+ "quality" : dec_data ["quality" ][0 ],
127
+ "type" : dec_data ["type" ][0 ],
128
+ "url" : dec_data ["url" ][0 ],
129
+ "sig" : dec_data ["sig" ][0 ],
130
+ "title" : video .Title ,
131
+ "author" : video .Author ,
132
+ "format" : dec_data ["format" ][0 ],
133
+ }
134
+
135
+ decodedVideo = append (decodedVideo , data )
136
+ logrus .Infof ("\n Decoded %d bytes of '%s" , in '%s ' format , len (decodedVideo ), dec_data ["quality" ][0 ], dec_data ["format" ][0 ])
110
137
}
111
138
112
- //Download data stream to memory.
113
139
114
- //convert video file to flv or mp3
115
-
116
-
117
- }
118
-
119
-
120
-
121
- func ApiDownloadVideo () {
122
-
123
-
140
+ //Download data stream to memory and convert to proper format
141
+ //NOTE: Use ffmpeg go bindings for this use case.
142
+
124
143
}
125
144
126
145
127
146
128
- func decodeVideoInfo (response string ) (streams streamList , err error ) {
129
- // decode
130
-
131
- answer , err := url .ParseQuery (response )
132
- if err != nil {
133
- err = fmt .Errorf ("parsing the server's answer: '%s'" , err )
134
- return
135
- }
147
+ func APIDownloadVideo (videoStream map [string ][]string ) ([]byte , err ) {
148
+ func (stream stream ) download (out io .Writer ) error {
149
+ url := stream .Url ()
136
150
137
- // check the status
151
+ log ( "Downloading stream from '%s'" , url )
138
152
139
- err = ensureFields ( answer , [] string { "status" , "url_encoded_fmt_stream_map" , "title" , "author" } )
153
+ resp , err := http . Get ( url )
140
154
if err != nil {
141
- err = fmt .Errorf ("Missing fields in the server's answer: '%s'" , err )
142
- return
155
+ return fmt .Errorf ("requesting stream: %s" , err )
143
156
}
144
-
145
- status := answer ["status" ]
146
- if status [0 ] == "fail" {
147
- reason , ok := answer ["reason" ]
148
- if ok {
149
- err = fmt .Errorf ("'fail' response status found in the server's answer, reason: '%s'" , reason [0 ])
150
- } else {
151
- err = errors .New (fmt .Sprint ("'fail' response status found in the server's answer, no reason given" ))
152
- }
153
- return
154
- }
155
- if status [0 ] != "ok" {
156
- err = fmt .Errorf ("non-success response status found in the server's answer (status: '%s')" , status )
157
- return
158
- }
159
-
160
- log ("Server answered with a success code" )
161
-
162
- /*
163
- for k, v := range answer {
164
- log("%s: %#v", k, v)
157
+ defer resp .Body .Close ()
158
+ if resp .StatusCode != 200 {
159
+ return fmt .Errorf ("reading answer: non 200 status code received: '%s'" , err )
165
160
}
166
- */
167
-
168
- // read the streams map
169
-
170
- stream_map := answer ["url_encoded_fmt_stream_map" ]
171
-
172
- // read each stream
173
-
174
- streams_list := strings .Split (stream_map [0 ], "," )
175
-
176
- log ("Found %d streams in answer" , len (streams_list ))
177
-
178
- for stream_pos , stream_raw := range streams_list {
179
- stream_qry , err := url .ParseQuery (stream_raw )
180
- if err != nil {
181
- log (fmt .Sprintf ("An error occured while decoding one of the video's stream's information: stream %d: %s\n " , stream_pos , err ))
182
- continue
183
- }
184
- err = ensureFields (stream_qry , []string {"quality" , "type" , "url" })
185
- if err != nil {
186
- log (fmt .Sprintf ("Missing fields in one of the video's stream's information: stream %d: %s\n " , stream_pos , err ))
187
- continue
188
- }
189
- /* dumps the raw streams
190
- log(fmt.Sprintf("%v\n", stream_qry))
191
- */
192
- stream := stream {
193
- "quality" : stream_qry ["quality" ][0 ],
194
- "type" : stream_qry ["type" ][0 ],
195
- "url" : stream_qry ["url" ][0 ],
196
- "sig" : "" ,
197
- "title" : answer ["title" ][0 ],
198
- "author" : answer ["author" ][0 ],
199
- }
200
-
201
- if sig , exists := stream_qry ["sig" ]; exists { // old one
202
- stream ["sig" ] = sig [0 ]
203
- }
204
-
205
- if sig , exists := stream_qry ["s" ]; exists { // now they use this
206
- stream ["sig" ] = sig [0 ]
207
- }
208
-
209
- streams = append (streams , stream )
210
-
211
- quality := stream .Quality ()
212
- if quality == QUALITY_UNKNOWN {
213
- log ("Found unknown quality '%s'" , stream ["quality" ])
214
- }
215
-
216
- format := stream .Format ()
217
- if format == FORMAT_UNKNOWN {
218
- log ("Found unknown format '%s'" , stream ["type" ])
219
- }
220
-
221
- log ("Stream found: quality '%s', format '%s'" , quality , format )
161
+ length , err := io .Copy (out , resp .Body )
162
+ if err != nil {
163
+ return fmt .Errorf ("saving file: %s (%d bytes copied)" , err , length )
222
164
}
223
165
224
- log ("Successfully decoded %d streams " , len ( streams ) )
166
+ log ("Downloaded %d bytes " , length )
225
167
226
- return
168
+ return nil
227
169
}
0 commit comments