gpt4 book ai didi

reactjs - 将 MediaRecorder 分块到 Google Cloud 平台时视频上传损坏

转载 作者:行者123 更新时间:2023-12-04 12:30:42 29 4
gpt4 key购买 nike

我目前正在使用 react hook 驱动的组件来记录我的屏幕,然后将其上传到 Google Cloud Storage。然而,当它完成时,在 Google Cloud 中创建的文件似乎已损坏。
这是我的 React 组件中代码的要点,其中 useMediaRecorder 来自此处:https://github.com/wmik/use-media-recorder ——

let {
error,
status,
mediaBlob,
stopRecording,
getMediaStream,
startRecording,
liveStream,
} = useMediaRecorder({
onCancelScreenShare: () => {
stopRecording();
},
onDataAvailable: (chunk) => {
// do the uploading here:
onChunk(chunk);
},
recordScreen: true,
blobOptions: { type: "video/webm;codecs=vp8,opus" },
mediaStreamConstraints: { audio: audioEnabled, video: true },
});
当数据通过这个钩子(Hook)变得可用时 - 它调用 onChunk( chunk ) 将一个二进制 Blob 传递给该方法,以执行上传,我结合这部分代码来执行上传:
 const onChunk = (binaryData) => {
var formData = new FormData();
formData.append("data", binaryData);
let customerApi = new CustomerVideoApi();
customerApi.uploadRecording(
videoUUID,
formData,
(res) => {},
(err) => {}
);
};
customerApi.uploadRecording 看起来像这样(使用 axios)。
const uploadRecording = (uuid, data, fn, fnErr) => {
axios
.post(endpoint + "/stream/upload", data, {
headers: {
"Content-Type": "multipart/form-data",
},
})
.then(function (response) {
fn(response);
})
.catch(function (error) {
fnErr(error.response);
});
};
HTTP 请求成功,一切顺利:要上传的服务器端代码基于 Laravel:
//这是 Controller 内部。
 public function index( Request $request )
{

// Set file attributes.
$filepath = '/public/chunks/';
$file = $request->file('data');
$filename = $uuid . ".webm";

// streamupload
File::streamUpload($filepath, $filename, $file, true);

return response()->json(['uploaded' => true,'uuid'=>$uuid]);

}
//有一个服务提供者用于在 File::对象上创建一个新宏,提供适当处理流的工具:
public function boot()
{
File::macro('streamUpload', function($path, $fileName, $file, $overWrite = true) {

$resource = fopen($file->getRealPath(), 'r+');

$storageClient = new StorageClient([
'projectId' => 'myprjectid',
'keyFilePath' => '/my/path/to/servicejson.json',
]);

$bucket = $storageClient->bucket('mybucket');
$adapter = new GoogleStorageAdapter($storageClient, $bucket);
$filesystem = new Filesystem($adapter);

return $overWrite
? $filesystem->putStream($fileName, $resource)
: $filesystem->writeStream($fileName, $resource);
});
}
所以重申:
  • React 应用程序将 blob 分块,
  • 服务器端决定是否应该在 Google Cloud Storage 中创建或附加
  • 服务器端成功。

  • 4) 谷歌云平台内的视频已损坏。
    但是,Google Cloud 容器内的视频文件已损坏且无法播放。我不确定它究竟为什么会损坏,但到目前为止我的猜测是:
  • 某种 Dodgy Mime 类型问题.. - 不同的浏览器似乎处理编解码器/文件类型与 mediarecorder 不同:例如Chrome 似乎是 x-matroska (.mkv?) - firefox 又不同了.. 理想情况下我会有一个 .webm 的容器 - 注意我如何设置文件名服务器端,它不是来自客户端。应该是?我不确定如何强制 MediaRecorder 成为特定的 mimeType - 我认为 blobOptions option 应该这样做,但更改扩展名和 mime 类型似乎对发生的损坏几乎没有影响。
  • 上传过程中出现的某种问题,其中 HTTP 请求未按顺序执行和完成 - 例如

  • 1 onDataAvailable completes second
    2 onDataAvailable completes first
    3 onDataAvailable completes third

    我已经排除了这一点,因为我认为这些块应该足够小。
  • 我正在使用的 Google Cloud Storage API 是否存在某种问题,可能是使用了错误的方式?云平台是否支持流媒体,这个库是否发送了正确的参数?
  • 我上传的方式存在某种问题 - axios header 应该是多部分表单数据还是其他内容?

  • 这是我用于服务器端的包: https://github.com/Superbalist/flysystem-google-cloud-storage
    任何人都可以阐明如何在不损坏 mediarecorder 的视频的情况下实现流式传输到 Google Cloud 的目标吗?希望问题中有足够的细节来帮助弄清楚。如图所示的问题不在于将文件获取到谷歌云,而是生成的文件无法以任何视频格式播放。
    更新
    我现在已经订购了我的块客户端,并在让它们到达服务器之前将它们正确排队。输出没有区别。正如一些人所建议的那样 - 单个 blob 上传请求工作正常。
    尝试使用可流式配置参数(从阅读源代码来看,在 Google 将它们识别为可恢复上传之前,块似乎需要具有特定大小
    $filesystem = new Filesystem($adapter, [
    '可恢复'=> 真
    ]);
    不确定如何: https://cloud.google.com/storage/docs/performing-resumable-uploads - 在我使用的库中实现,(或者在 Google Cloud API 本身中实现?)。我需要自己实现吗?谷歌的文档很简单。

    最佳答案

    精简版:
    您应该做的第一件事是在本地缓冲整个视频,然后将单个有效负载发送到服务器和谷歌驱动器。这将验证您的小视频代码实际上是正确的。一旦您可以验证这一点,您就可以继续处理多块上传。
    更长的版本:
    首先,您没有通过 uuid对于请求,它正在被使用:

    const uploadRecording = (uuid, data, fn, fnErr) => {
    axios
    .post(endpoint + "/stream/upload", data, {
    headers: {
    "Content-Type": "multipart/form-data",
    },
    })
    .then(function (response) {
    fn(response);
    })
    .catch(function (error) {
    fnErr(error.response);
    });
    };
    接下来,你不能相信分块是如何工作的,我认为你用块日志记录的乱序结果验证了这种行为。您需要假设在您的服务器上您将获得无序的块并正确处理它们。
    您在服务器上获得的每个块都需要放在正确的位置,您不能只是“writeStream”,您需要写入显式的二进制块。具体来说,在每个请求上指定字节范围: Google docs :
    curl -i -X PUT --data-binary @CHUNK_LOCATION \
    -H "Content-Length: CHUNK_SIZE" \
    -H "Content-Range: bytes CHUNK_FIRST_BYTE-CHUNK_LAST_BYTE/TOTAL_OBJECT_SIZE" \
    "SESSION_URI"
    • CHUNK_LOCATION is the local path to thechunk that you're currently uploading.
    • CHUNK_SIZE is the number ofbytes you're uploading in the current request. For example, 524288.
    • CHUNK_FIRST_BYTE is thestarting byte in the overall object that the chunk you're uploadingcontains.
    • CHUNK_LAST_BYTE is the ending byte in theoverall object that the chunk you're uploading contains.
    • TOTAL_OBJECT_SIZE is the total size of theobject you are uploading.
    • SESSION_URI is the value returned in theLocation header when you initiated the resumable upload.

    关于reactjs - 将 MediaRecorder 分块到 Google Cloud 平台时视频上传损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65602021/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com