Inconsistent serialization between `render` and `studio` of the `calculateMetadata` result
Bug Report 🐛
I created the following composition:
<Composition
fps={30}
id="NoSerializeComposition"
height={720}
width={1280}
durationInFrames={10}
calculateMetadata={() => {
return {
props: {
calculated: new Vector2(10, 10),
},
}
}}
defaultProps={{
calculated: undefined,
}}
component={({ calculated }: { calculated?: Vector2 }) => {
const value = `${calculated}`
console.log(value)
return (
<AbsoluteFill>
<h1>{value}</h1>
</AbsoluteFill>
)
}}
/>
export class Vector2 {
readonly x: number
readonly y: number
constructor(x: number, y: number) {
this.x = x
this.y = y
}
toString(): string {
return `Vector2 [X: ${this.x}, Y: ${this.y}]`
}
}
Key points from this example:
- The
calculateMetadatareturns a non-serializableclass,Vector2 - The studio displays the following string:
Vector2 [X: 10, Y: 10] - The render displays the following string:
[object Object], which means it is no longer theVector2class
I think this is a bug, because:
- The documentation of
calculateMetadatadoes not mention any restrictions regarding non-serializable objects - The serialization restrictions should only be for
inputPropsaccording to the docs, but this is no longer theinputProps - It is inconsistent between the two modes
Is there a way to undo this serialization?
Thank you!
Thanks for reporting!
Objects are being passed between browser and Node.js and there is no useful way of undoing serialization of classes. We'll fix this by updating the docs to explicitly disallow non-JSON-serializable values.
To still improve it, in the next version the serialization will be consistent and in the Studio it will also turn into an object, to catch this earlier in the developer journey.
Makes sense, thanks. Based on your comments I got a better understanding of how Remotion works.
Couple minor doc comments I feel is missing from calculateMetadata is that:
- it runs a single time, independent of the worker count (or
concurrencydefined inrenderMedia) - it runs in a separate node process when rendering, executed whenever
selectCompositionis called