Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rumble video embed #981

Closed
wants to merge 7 commits into from
Closed

Conversation

benalleng
Copy link
Contributor

@benalleng benalleng commented Mar 26, 2024

Closes #134 but if this works as we hope I am hoping to add in the embed functionality for other sites as well

Embeds rumble video embed links, unfortunately rumble is weird and what you see at the top is not the embed link you want like it is on youtube but thats the price you pay i guess for their revenue share model.
It has to do with the fact that embeded videos have a different revenue share percentage so keeping track of how to divide the money is too difficult when everyone is downloading the video from the same url (I'm guessing)

Rumble vs a Youtube embed
image

This standard <iframe/> model should be able to be used on many sites so maybe once we do some quick QA on this I could try and add a more general "video embed" that parses video embeds from several of the other popular video sites

I'm going to have this PR open for now but if we want to add embedding for more sites i can put it into draft untl the logic is finished for those as well

Summary by CodeRabbit

  • New Features
    • Introduced a new component for enhanced link rendering, including special handling for YouTube and Rumble video links.
  • Security Updates
    • Updated content security policy to allow embedding from rumble.com, alongside existing permissions for www.youtube.com and platform.twitter.com.

Copy link
Contributor

coderabbitai bot commented Mar 26, 2024

Walkthrough

The update introduces a refined approach for handling video links and embedding within a React application. It involves the addition of iframe imports, the creation of a new A component to dynamically render links—specifically targeting YouTube and Rumble video platforms—and the reassignment of link rendering logic to this component. Additionally, it updates middleware security policies to include rumble.com for iframe sources, enhancing the application's content embedding capabilities and security.

Changes

Files Change Summary
components/text.js Introduced iframe import, new A component for link rendering, updated a tag handling
middleware.js Added rumble.com to frame-src directive in CSP, alongside YouTube and Twitter platforms

Related issues

  • Rumble video embed like what was added for Youtube #134: The PR seems to address the request for Rumble video embed support by updating middleware to accept rumble.com as a source and by refining link rendering logic to handle Rumble video links. This aligns with the issue's objective to enhance video embedding features.

Poem

In the code where links do weave,
A rabbit hops, in bytes believes.
🐇💻 With iframe and A, it plays,
Embedding tales from Rumble's bays.
YouTube and Twitter, now with a friend,
In digital meadows, their videos blend.
🌟 To share, to view, in harmony's trend.

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share

Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • The JSON schema for the configuration file is available here.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/coderabbit-overrides.v2.json

CodeRabbit Discord Community

Join our Discord Community to get help, request features, and share feedback.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 2

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between b4cef44 and c1083f0.
Files selected for processing (2)
  • components/text.js (3 hunks)
  • middleware.js (1 hunks)
Additional comments: 2
middleware.js (1)
  • 44-44: The addition of rumble.com to the frame-src directive of the CSP is necessary for embedding Rumble videos. Ensure that rumble.com is a trusted source and consider the security implications of allowing content from this source.
components/text.js (1)
  • 242-242: Updating the a tag handler in remarkPlugins to use the new A component ensures that all links are rendered using the centralized logic. This is a good practice for maintainability and consistency.

components/text.js Outdated Show resolved Hide resolved
components/text.js Outdated Show resolved Hide resolved
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between b4cef44 and a3c2332.
Files selected for processing (2)
  • components/text.js (2 hunks)
  • middleware.js (1 hunks)
Files skipped from review as they are similar to previous changes (2)
  • components/text.js
  • middleware.js

Copy link
Member

@ekzyis ekzyis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR!

That it doesn't work for direct links is unfortunate. Did you check if there is a way to fetch the embed link from direct links? If not possible, that's okay. Maybe that's even too complicated so not worth it. I think stackers will learn fast to use embed links with rumble.

I noticed three other things though:

  1. The regexp is not matching for links without start and for links where pub contains letters.
  2. We also want this to work for link posts. This currently only works for links inside a post description or comment. So the rumble embed code also needs to be added to ItemEmbed which you can find in components/item-full.js. That means (more) duplicate code though so if you want, you can try to refactor it. Not necessary for this PR though, I usually like create separate PRs ("stacked PRs") for stuff like this anyway.

2024-03-27-153441_1920x1080_scrot

  1. I think we don't need to use error-prone regexp's but can use the URL constructor. See my comment.

}

// if the link is to a rumble video, render the video
const rumble = href.match(/(?:https?:\/\/)?(?:www\.)?rumble\.com\/embed\/(?<id>[a-z0-9]+)\/\?pub=\d+&start=(?<start>\d+)/i)
Copy link
Member

@ekzyis ekzyis Mar 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested with this URL: https://rumble.com/embed/v17j3tt/?pub=3fid3f

As you can see, pub can be alphanumeric so you want to use [a-z0-9]+ or \w+ for it. And start should not be required to match.

I noticed that we could probably leverage the URL constructor here for parsing as I did in parseInternalLinks (see #765 (comment)). I think this would make this easier and cleaner.

The other twitter and youtube embed code you can see here is just old and bad and isn't using them yet.

If you want to refactor the existing embed code to also use the URL constructor for parsing, I recommend doing this in a separate PR.

@benalleng
Copy link
Contributor Author

benalleng commented Mar 27, 2024

Thanks for the feedback! Regex creation is definitely a skill I have not grasped yet lol I'll take a brief look at the refactor as well if we intend to add embeds for many different sites it might be worth pulling them up to be reused in multiple places

Did you check if there is a way to fetch the embed link from direct links?

Short of scraping the data somehow when loading in from the standard link I don't think its possible. in the rumble embed tutorial video https://rumble.com/v1a59rb-rumble-basics-how-to-embed-your-video.html they talk about how embeded videos get an 80% revenue share so I imagine they don't want us to be able to claw back that 20% on a simple script

If you want to refactor the existing embed code to also use the URL constructor for parsing, I recommend doing this in a separate PR.

Ok I will try to get this rumble embed right first and then I can come back through with a refactor

@huumn
Copy link
Member

huumn commented Mar 27, 2024

Nice iframe solution!

Embeds rumble video embed links, unfortunately rumble is weird and what you see at the top is not the embed link you want like it is on youtube but thats the price you pay i guess for their revenue share model.

I don't think we can expect people to share the right url, so if we want this to be used, we'll probably want to make it work for either url:

  1. if it's the embed url, use your solution as is
  2. if it's the url someone is likely to copy and paste onto SN, fetch the url on the client and parse out the embed link, then replace the copied url

@benalleng
Copy link
Contributor Author

benalleng commented Mar 27, 2024

fetch the url on the client and parse out the embed link, then replace the copied url

Ok! yeah i think i was overthinking it, good idea! i'll give that a try!

@benalleng benalleng marked this pull request as draft March 28, 2024 04:15
@benalleng
Copy link
Contributor Author

Converting to draft for now until I can get a better sense of how to fetch the embed link.

@ekzyis
Copy link
Member

ekzyis commented Mar 28, 2024

fetch the url on the client and parse out the embed link, then replace the copied url

Ok! yeah i think i was overthinking it, good idea! i'll give that a try!

I am confused. Maybe my English was confusing but that's what I meant with

Did you check if there is a way to fetch the embed link from direct links?

Short of scraping the data somehow when loading in from the standard link I don't think its possible. [...]

However, I forgot that we're already scraping websites to auto-populate titles + publication date here with domino, a server-side DOM implementation. Might be interesting code to look at for you. (It's on the server though.)

@benalleng
Copy link
Contributor Author

benalleng commented Mar 28, 2024

I am confused. Maybe my English was confusing but that's what I meant with

No you're fine! That's on me I just wasn't thinking

</div>
)
} else {
return null
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added these return nulls for now As i was hoping to create some logic for when the user's link does Not follow the expected embed format but at the moment no logic for that in rumble

@benalleng
Copy link
Contributor Author

benalleng commented Mar 29, 2024

I cleaned up the logc for rumble and added the embeds for link posts as well. Also in my attempts to find a solution for our embed vs non-embeded links I realized odysee handles embeds more simply.

I am a little stuck with the client-side fetching, I either am unable to get the tool to work like domino or puppeteer as they seem to be designed for server-side or when trying to fetch the data directly with some basic fetch logic I am getting CORS errors. @ekzyis any thoughts on another avenue I could try? I breifly looked at the naming convention between https://rumble.com/embed/v17j3tt/?pub=3fid3f and https://rumble.com/v1a59rb-rumble-basics-how-to-embed-your-video.html but I couldn't find any way to decode or parse one id from the other.

@huumn
Copy link
Member

huumn commented Mar 29, 2024

I'd think you can just fetch the page then regex parse for /embed/ or something in the body.

const response = await fetch(ensureProtocol(url))
const html = await response.text()
if (url.includes('peertube.tv')) {
return html.match(/"([^"]*\/embed\/[^"]*)"/)[0].substring(1, html.match(/"([^"]*\/embed\/[^"]*)"/)[0].length - 1)
Copy link
Contributor Author

@benalleng benalleng Apr 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the parse for the peertube html to prove to myself that this method works, it looks for the embed link and then trims the " " on either end

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From my brief investigation becauses bitcoin.tv is based on peertube it should have the exact same format so we should be able to use this exact code for parsing links from there as well

@@ -553,6 +553,17 @@ export default {

return res
},
fetchDocument: async (parent, { url }, { models }) => {
try {
const response = await fetch(ensureProtocol(url))
Copy link
Contributor Author

@benalleng benalleng Apr 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no matter how hard I tried to play with fetching and the link rumble would not let me fetch for any link with the format https://rumble.com/vabc1234-some-rumble-video.html, perhaps I am missing some additional step but this does work with peertube as expected

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The really confusing thing is that when I test a get request with this rumble link in something like postman, it works

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What kind of errors are you getting on fetch?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is the error object being thrown

{
	"errors": [
		{
			"message": "fetch failed",
			"locations": [
				{
					"line": 2,
					"column": 3
				}
			],
			"path": [
				"fetchDocument"
			],
			"extensions": {
				"code": "INTERNAL_SERVER_ERROR",
				"stacktrace": [
					"Error: fetch failed",
					"    at Object.fetchDocument (webpack-internal:///(api)/./api/resolvers/item.js:578:23)",
					"    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)"
				]
			}
		}
	],
	"data": {
		"fetchDocument": null
	}
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow that's not descriptive at all. Regardless, I think we want to call this on the client.

Have you tried fetching in your browser console?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I fetch from the frontend or the console I get CORS errors
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://rumble.com/v1a59rb-rumble-basics-how-to-embed-your-video.html. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 200.
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://rumble.com/v1a59rb-rumble-basics-how-to-embed-your-video.html. (Reason: CORS request did not succeed). Status code: (null).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, that makes sense. CORs is a pain.

I'd try getting a more descriptive error on the server.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was having a look at #879 and I was curious if rumble had a similar cors policy so I gave it a test by using this https://github.com/Rob--W/cors-anywhere as a test to see if I could grab the embed link and it works!

Note the html link but it still renders the embeded video
image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

didn't implement it in the sn repo yet, I just added the demo https://cors-anywhere.herokuapp.com/ server as a prefix to the url

@huumn
Copy link
Member

huumn commented May 28, 2024

Closing after #1191 was merged

@huumn huumn closed this May 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Rumble video embed like what was added for Youtube
3 participants