video_info icon indicating copy to clipboard operation
video_info copied to clipboard

Facebook support

Open vheuken opened this issue 8 years ago • 21 comments

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

vheuken avatar Mar 11 '16 20:03 vheuken

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.

vheuken avatar Mar 15 '16 01:03 vheuken

@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.

vheuken avatar Mar 15 '16 18:03 vheuken

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.

vheuken avatar Mar 15 '16 19:03 vheuken

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.

drakmail avatar Mar 15 '16 20:03 drakmail

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.

thibaudgg avatar Mar 15 '16 20:03 thibaudgg

@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.

vheuken avatar Mar 15 '16 21:03 vheuken

https://github.com/nov/fb_graph2 might be worth looking into to see how they handle things.

vheuken avatar Mar 15 '16 21:03 vheuken

Ah, here we go: https://github.com/nov/fb_graph2/wiki/Obtain-Access-Tokens

I'll look into this more in a bit.

vheuken avatar Mar 15 '16 21:03 vheuken

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.

vheuken avatar Mar 16 '16 03:03 vheuken

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).

vheuken avatar Mar 16 '16 03:03 vheuken

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)

vheuken avatar Mar 16 '16 09:03 vheuken

@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.

vheuken avatar Mar 16 '16 10:03 vheuken

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!

thibaudgg avatar Mar 16 '16 11:03 thibaudgg

Sounds really good, but does #thumbnail_medium and #thumbnail_smallmethods will be exists for providers that doesn't provide that sizes?

drakmail avatar Mar 16 '16 13:03 drakmail

@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 avatar Mar 16 '16 16:03 vheuken

@vheuken I think it's better to return nil rather than raise an exception or return same thumbnail.

drakmail avatar Mar 16 '16 18:03 drakmail

Perfect. I'll go for that then.

vheuken avatar Mar 16 '16 18:03 vheuken

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.

vheuken avatar Mar 18 '16 18:03 vheuken

Looks like we can't get the dimensions of Facebook videos, so #width and #height will have to return nil for now.

vheuken avatar Mar 19 '16 05:03 vheuken

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/

Brotakuu avatar Apr 09 '16 09:04 Brotakuu

Good idea. I'll look into that.

vheuken avatar Apr 10 '16 19:04 vheuken