video_info
video_info copied to clipboard
Facebook support
Facebook support would probably be a good feature to add. It looks like they have an API for video data: https://developers.facebook.com/docs/graph-api/reference/video
Looks like it will require an API key, so we'll need a scraper as well.
2.3.0 :022 > response = Net::HTTP.get('graph.facebook.com', '/v2.5/1076265379062823')
=> "{\"error\":{\"message\":\"An access token is required to request this resource.\",\"type\":\"OAuthException\",\"code\":104,\"fbtrace_id\":\"FEuLi1b1yB3\"}}"
Info on API keys should be found here: https://developers.facebook.com/docs/facebook-login/access-tokens
The Facebook API is basically useless to us. There is no "API Key" necessarily, just OAuth stuff that requires some form of user authentication, so we'll have to resort to just page scraping.
@thibaudgg Bit of an issue. I've implemented #author
, #author_url
, and #author_thumbnail
just fine (though just for one URL type). It seems that we can't get duration or video thumbnail because Facebook loads that content dynamically. We can still get the description (Facebook videos don't really have a title). With such little actual video content, I'm starting to think that this isn't worth it since most of the content we actually can get is just about the post, not the video itself.
You can verify what I said by opening up the source of a Facebook video URL and searching for "mediaPresentationDuration=", then doing a wget on the page. It just isn't there and there doesn't seem to be any other alternative info.
Parsing facebook is a really bad idea. I tried to do it some time ago – it's almost impossible :-)
There are could be an easy way to get the access token (according to this SO answer: http://stackoverflow.com/a/8932353/979469) to use Graph API. Maybe it's better than trying to parse pages.
If scraping is not really an option, I guess we should try to only use the API with a valid token and forget about the other possibilities. I'm fine with that.
@drakmail It seems like the closest I can find is a a "Client Token". Using it as an access token gives me 400 "Invalid OAuth access token"....so I'm not really sure where to go from here. I'm not sure how much the FB API has changed, but the answer was from over four years ago, so things are likely a bit different now.
https://github.com/nov/fb_graph2 might be worth looking into to see how they handle things.
Ah, here we go: https://github.com/nov/fb_graph2/wiki/Obtain-Access-Tokens
I'll look into this more in a bit.
FINALLY got the basic API working. Turns out you can substitute an access token (which needs to be generated, which isn't really doable for us) with both your app-id and app-secret like so: app_id|app_secret
So the URI ends up being:
'https://graph.facebook.com/v2.5/{video_id}?access_token={app_id}|{app_secret}'
That being said, here's all the data I got from it:
"{\"description\":\"If he visits you it's to late\",\"updated_time\":\"2016-02-27T06:18:05+0000\",\"id\":\"1071390929550268\"}"
Though looking at the documentation we should be able to get more info. I just gotta figure out how to pass in the parameters (should be simple; I'm just tired)
Of course, testing this would require having the app_secret in the specs.........not sure if that is a good idea. I guess it won't be a big issue.
Ok that was obvious: fields={parameters}
'https://graph.facebook.com/v2.5/1071390929550268?fields=from,description,length&access_token=app_id|app_secret'
Gives:
> response.body
=> "{\"from\":{\"name\":\"\\u30d5\\u30ec\\u30c3\\u30c9YOLO\",\"id\":\"593748813981151\"},\"description\":\"If he visits you it's to late\",\"length\":9.509,\"id\":\"1071390929550268\"}"
(Name looks screwy because it has some unicode characters)
Cool. So now this should be pretty simple to implement. Of course, we'll have to have a way for users to enter in an app id and a secret. maybe just:
VideoInfo.provider_api_keys = { facebook_app_id: 'app_id', facebook_app_secret: 'app_secret' }
?
And of course, we can/should let them just do { facebook_access_token: 'access_token' }
if they're generating their own access token, though we'd need to mock something for automated testing...
(Sorry for the walls of text; mostly using this as notes for myself).
Got #author
, #author_url
, #description
, and #duration
implemented. I'll try to get the rest in soon.
I also need to test more URL types, but that can come after initial implementation.
You can follow the progress here: https://github.com/vheuken/video_info/tree/facebook (I'll submit a PR when it's close to done)
@thibaudgg It looks like there is only one available thumbnail for a video (at least, that's all the API provides). Assuming we're stick with just one, how would we go about naming that? Our current convention seems to be #thumbnail_large
, #thumbnail_medium
, and #thumbnail_small
.
My idea is to have a default method #thumbnail
for all VideoInfo objects that is just aliased to #thumbnail_large
by default and is used exclusively for providers where only one thumbnail size is available (like Facebook seems to be). Thoughts?
https://scontent.xx.fbcdn.net/hvthumb-xpa1/v/t15.0-10/p160x160/12720103_1071391039550257_1997979656_n.jpg?oh=c29fe72d1d3a5be4e81071a0cd877a9a&oe=57528694 example of a thumbnail obtained from the API.
My idea is to have a default method #thumbnail for all VideoInfo objects that is just aliased to #thumbnail_large by default and is used exclusively for providers where only one thumbnail size is available (like Facebook seems to be). Thoughts?
Sounds good!
Sounds really good, but does #thumbnail_medium
and #thumbnail_small
methods will be exists for providers that doesn't provide that sizes?
@drakmail I'm not sure, actually. I mean, I'd say no or having them return nil
, but I haven't really given it any thought. Any preference? Having them all return the same thumbnail doesn't sound right to me since then it's not actually doing what the API says it is doing.
@vheuken I think it's better to return nil
rather than raise an exception or return same thumbnail.
Perfect. I'll go for that then.
I mentioned this in the PR, but I'm restating it here so that I remember that it needs to be documented:
While #{app_id}|#{app_secret}
works for public videos on pages, we need an actual "user authentication token" for user videos (even if they're public). The issue is that getting one involves a user logging in, so it isn't really an option for automated testing. Also, what videos you can get info on depends on the user, which would further complicate automated testing. Here is my solution:
Allow users the option to enter an actual access token, and we only test that the access token is the preferred way to handle things and then just trust that the FB API works. We can also test that it falls back to #{app_id}|#{app_secret}
if they are provided.
Once I get that in, I'll try to do some manual testing (make a tiny little test app) to make sure it does work as expected.
We'll need to clearly explain the situation to end users. We should probably clean up the documentation to help with this, as the README is getting a bit long and unwieldy. I'll make an issue for this later.
Looks like we can't get the dimensions of Facebook videos, so #width
and #height
will have to return nil
for now.
This would be a very timely feature with the new facebook live videos platform released. http://newsroom.fb.com/news/2016/04/introducing-new-ways-to-create-share-and-discover-live-video-on-facebook/
Good idea. I'll look into that.