Skip to main content

处理用户视频上传

在一个用户可以上传和编辑视频的应用中,我们可以通过在上传完成之前就将视频加载到播放器中来创造更好的用户体验。好消息是:这可以很容易实现!

🌐 In an app where users can upload videos and edit them, we can create a better user experience by loading the video into a player even before the upload is finished. Good news: This can be done pretty easily!

允许用户上传

🌐 Allowing user uploads

我们有一个组件,它返回一个 <OffthreadVideo> 标签,该标签包含一个 URL 作为源。

🌐 We have a component which returns a <OffthreadVideo> tag that includes an URL as source.

MyComposition.tsx
import {AbsoluteFill, OffthreadVideo} from 'remotion'; type VideoProps = { videoURL: string; }; export const MyComponent: React.FC<VideoProps> = ({videoURL}) => { return ( <AbsoluteFill> <OffthreadVideo src={videoURL} /> </AbsoluteFill> ); };

视频 URL 将从 Remotion 播放器传递到我们的组件。
使用 <input type="file"> 元素,我们允许用户上传。
一旦文件完全上传到云端,URL 将被设置,并可以被组件用来显示视频。

🌐 The video URL will be passed from the Remotion Player to our component.
Using a <input type="file"> element, we allow a user upload.
As soon as a file is fully uploaded to the cloud, the URL will be set and can be used by the component to display the video.

App.tsx
import {Player} from '@remotion/player'; import {useState} from 'react'; export const RemotionPlayer: React.FC = () => { const [videoUrl, setVideoUrl] = useState<string | null>(null); const handleChange = useCallback(async (event: React.ChangeEvent<HTMLInputElement>) => { if (event.target.files === null) { return; } const file = event.target.files[0]; //upload is an example function & returns a URL when a file is uploaded on the cloud. const cloudURL = await upload(file); // E.g., cloudURL = https://exampleBucketName.s3.ExampleAwsRegion.amazonaws.com setVideoUrl(cloudURL); }, []); return ( <div> {videoUrl === null ? null : <Player component={MyComposition} durationInFrames={120} compositionWidth={1920} compositionHeight={1080} fps={30} inputProps={{videoUrl}} />} <input type="file" onChange={handleChange} /> </div> ); };

upload() 函数的实现依赖于提供者,我们在本文中没有展示其实现。我们假设它是一个接收文件、上传并返回 URL 的函数。

🌐 The implementation of the upload() function is provider-specific and we do not show an implementation in this article. We assume it is a function that takes a file, uploads it and returns an URL.

乐观更新

🌐 Optimistic updates

当我们开始上传文件时,我们可以使用 URL.createObjectURL() 创建一个 blob URL,该 URL 可用于在 <Video> 标签中显示本地文件。当文件上传完成并且我们获得远程 URL 后,组件应使用远程 URL 作为源。

🌐 When we start the upload of the file, we can create a blob URL using URL.createObjectURL() which can be used to display the local file in a <Video> tag. When the file is done uploading and we get the remote URL, the component shall use remote URL as source.

App.tsx
import {Player} from '@remotion/player'; import {useCallback, useState} from 'react'; type VideoState = | { type: 'empty'; } | { type: 'blob' | 'cloud'; url: string; }; export const RemotionPlayer: React.FC = () => { const [videoState, setVideoState] = useState<VideoState>({ type: 'empty', }); const handleChange = useCallback(async (event: React.ChangeEvent<HTMLInputElement>) => { if (event.target.files === null) { return; } const file = event.target.files[0]; const blobUrl = URL.createObjectURL(file); setVideoState({type: 'blob', url: blobUrl}); const cloudUrl = await upload(file); setVideoState({type: 'cloud', url: cloudUrl}); URL.revokeObjectURL(blobUrl); }, []); return ( <div> {videoState.type !== 'empty' ? <Player component={MyComposition} durationInFrames={120} compositionWidth={1920} compositionHeight={1080} fps={30} inputProps={{videoUrl: videoState.url}} /> : null} <input type="file" onChange={handleChange} /> </div> ); };

这将导致用户在将视频拖入输入字段时立即看到视频。在本地视频不再使用后调用 URL.revokeObjectURL() 是一种良好的做法,以释放已使用的内存。

🌐 This will result in the user immediately seeing the video as they drag it into the input field. It is a good practice to call URL.revokeObjectURL() after the local video is not used anymore to free up the used memory.

note

请尽快用真实 URL 替换 blob: URL。
由于 blob: URL 不支持 HTTP Range 头,在使用 blob: URL 时视频搜索性能会下降。

验证视频兼容性

🌐 Validating video compatibility

在上传视频之前,你应该验证浏览器是否可以解码它。这可以节省带宽并为用户提供即时反馈。有关验证用户视频的完整指南,包括处理不兼容格式,请参见 验证用户视频

🌐 Before uploading a video, you should validate whether the browser can decode it. This saves bandwidth and provides immediate feedback to the user. For a complete guide on validating user videos including handling incompatible formats, see Validating user videos.

另请参阅

🌐 See also