remotion-dev / remotion

🎥 Make videos programmatically with React
https://remotion.dev
Other
20.98k stars 1.06k forks source link

Dynamically set `width` and `height` & FPS #808

Closed tomByrer closed 2 years ago

tomByrer commented 2 years ago

Issuehunt badges

Edit by @JonnyBurger:

🎃 This issue is part of our Hacktoberfest campaign! 📚 Read more about Hacktoberfest here ✅ This issue is currently assigned to @exitflynn!

Hacktoberfest acceptance criteria:


Original issue:

Use Case

Rapidly changing FPS & video size for:

Problem

While it is clear Remotion uses Frames and FramesPerSecond for time, & pixels for size, these are inconvenient standards for dynamic situations. For example, the movie producer, SEO professional, etc who wants to change the video size & rate easily can not when the components hard-coded.

While everyone could hard-code their own way of handling translations, it would hinder sharing components & complicate development.

Possible Solutions

Unsure best way forward; here is a brainstorm of easiest to complex implementation:


IssueHunt Summary #### [exitflynn exitflynn](https://issuehunt.io/u/exitflynn) has been rewarded. ### Backers (Total: $167.00) - [jonnyburger jonnyburger](https://issuehunt.io/u/jonnyburger) ($112.00) - [remotion-dev remotion-dev](https://issuehunt.io/u/remotion-dev) ($55.00) ### Submitted pull Requests - [#1427 add --height --width flags](https://issuehunt.io/r/remotion-dev/remotion/pull/1427) --- ### Tips - Checkout the [Issuehunt explorer](https://issuehunt.io/r/remotion-dev/remotion/) to discover more funded issues. - Need some help from other developers? [Add your repositories](https://issuehunt.io/r/new) on IssueHunt to raise funds.
JonnyBurger commented 2 years ago

I'll break the issue down into it's parts:

Note: For now, you can create two compositions with the same component but different dimensions. If you want to create a responsive video, this is cool, because you can preview both styles.

tomByrer commented 2 years ago

create two compositions with the same component but different dimensions

I'm trying to avoid this, but sometimes might be needed, eg if the aspect ratio changes radically between YouTube & FaceBook/Instagram/TickTok.

The other suggestions are good, but I might have different ideas, so I guess I'll have to build demos.

tomByrer commented 2 years ago

I changed the title due to one of my use cases, which is actually my primary concerns:

  • dynamic playback (Responsive, keep in sync with imbedded video)
  • Changing FPS when source data is in seconds (eg WebVTT)

But I failed in being too vague. My main use for Remotion is to use it along with typical videos (eg from YouTube, Vimo, etc):

I do have use cases for rendering to different social media platforms, but that is not my main worry.

tomByrer commented 2 years ago

Past my bedtime so sorry for being terse, but here is a demo I've worked on: https://github.com/tomByrer/remotion-demo-compose

Quick code examples:

// id, width, height are calculated
// fps default is 30
//TODO: send total time from <Series> to parent <Composition>
<Helper.AdvancedComposition
  component={AboutRemotion}
  durationInSeconds={14}
  resolution='story'
/>
/* useConvert.js */
import {useVideoConfig} from 'remotion'

export function seconds(sec){
    const videoConfig = useVideoConfig()
    return sec * videoConfig.fps
}

export function vh(h){
    const videoConfig = useVideoConfig()
    return h * videoConfig.height * 0.01
}

export function vw(w){
    const videoConfig = useVideoConfig()
    return w * videoConfig.width * 0.01
}
...
/* useAnimation.js */
import {interpolate, spring, useCurrentFrame, useVideoConfig} from 'remotion'
import * as useConvert from '../helpers/useConvert';

export function fadeIn(seconds=0.5){
    const frame = useCurrentFrame()
    return interpolate(
        frame,
 // frames conversions makes changing FPS instant
// & seconds are easier to wrap mind around
        [0, useConvert.seconds(seconds)],
        [0, 1]
    )
}
...
/* 
/* SomeComponant.jsx */
import * as useConvert from '../helpers/useConvert';
// although the viewport ratios are hard to read, they are responsive
<div style={{
    fontSize: useConvert.vw(3.7234),
    bottom: useConvert.vh(12.9629),
    opacity: useAnimation.useFadeIn(),
}}
>test div</div>
issuehunt-oss[bot] commented 2 years ago

@jonnyburger has funded $111.00 to this issue.


issuehunt-oss[bot] commented 2 years ago

@jonnyburger has funded $1.00 to this issue.


issuehunt-oss[bot] commented 2 years ago

@remotion-dev has funded $55.00 to this issue.


exitflynn commented 2 years ago

Hi @JonnyBurger I'd love to take up this issue!

JonnyBurger commented 2 years ago

@exitflynn Assigned! Good luck!

exitflynn commented 2 years ago

hello! this one's taking me a bit longer than i expected, still on it though!

exitflynn commented 2 years ago

hello there! :wave: i must admit that i was very much a newbie when it came to React and contributing to Open-Source in general when I took this issue up. I had seen the fireship video on Remotion and found the idea to be really neat. While I wanted to start contributing to open-source this hacktoberfest, I decided to search my history for nice repo's I had saved for later, remotion came up and with the added motivation of the issuehunt and the hacktoberfest tags, this issue seemed doable for me. I have been building my React knowledge since then and finally recently managed to start making some progress :cowboy_hat_face: :partying_face: (while managing my college and some volunteering work on the side). I'm not sure why but i just felt like letting you know, this is my first time contributing to a repo in a way that is not non-code :sweat_smile:

exitflynn commented 2 years ago

I wanted to clarify which option would be more suitable, putting the setHeight and getHeight under Rendering or under the Output configType? (for reference)

JonnyBurger commented 2 years ago

@exitflynn That's awesome to hear! Love to hear a story of someone getting successfully started!

Both seems okay, if uncertain, you can put it in Config.Output!

exitflynn commented 2 years ago

Thank you soo much for that response!

Apologies but major beginner question ahead, I am having trouble being able to figure out how to access the hardcoded values like the height and width of the video which the user would have specified. I am currently thinking that they'd be the ones in internals and could be accessed like so:

const video = Internals.useVideo();
const height = video.height;

But since I am to work with the lambda cli functions, an inner voice inside me felt a little uneasy that I am not even touching the lambda directory. I am unable to figure out if the changes made in cli/ carry over to lambda/ cli commands, with just the added lambda prefix or is some sort of bridging or rewriting is necessary, I'm really sorry if the question is too abstract and/or broad and would really appreciate any feedback.

JonnyBurger commented 2 years ago

@exitflynn Sure!

Using useVideo() you only access the height and width once they have been set. The scope of the issue is to define the height and width explicitly before they even reach useVideo().

Check out this location in the codebase: https://github.com/remotion-dev/remotion/blob/main/packages/cli/src/render.tsx#L187

In the config variable, we have various metadata such as width, height and fps. They get pulled from your React code - here it would be great as a first step to, if someone passes --width or --height in the command line, ignore those values and overwrite the config object! Check out the parse-command-line.ts file as well and the variable parsedCli that it exposes.

That is actually already a significant part of the functionality, the other part is to just port it to also to the still and lambda commands and to then update the documentation!

exitflynn commented 2 years ago

hey jonny! Thanks again for the response. So, I came up with that ^, and just wanted to make sure if this works just in case there's something here that I'm fundamentally missing.

edit: PR #1427 :cowboy_hat_face:

issuehunt-oss[bot] commented 2 years ago

@jonnyburger has rewarded $150.30 to @exitflynn. See it on IssueHunt

JonnyBurger commented 2 years ago

Fixed by #1427

ammar-bay commented 1 year ago

@JonnyBurger Hey man, I just wanted to ask how can I dynamically set height in renderMedia() @tomByrer said above that you can override the composition object, how can I do that?

selectComposition() should have a width and height props to configure this, but there isnt. What other way do I have to do acheive this

leonmak commented 11 months ago

@ammar-bay renderMediaOnLambda has

forceHeight: body.height,
forceWidth: body.width,