Flutter摄像头录制的视频与浏览器不兼容-如何转换为.mp4



我正在尝试捕获一个视频并将其上传到firebase存储。

问题是,录制的视频格式是.mov,而且这种格式似乎与浏览器不兼容。

如何将录制的文件转换为.mp4

下面是我用来录制和上传视频的代码。

import 'dart:io';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
import 'package:video_player/video_player.dart';
import 'package:flutter/services.dart' show rootBundle;
import 'package:path_provider/path_provider.dart';
class CameraTestPage extends StatefulWidget {
const CameraTestPage({Key? key}) : super(key: key);
@override
_CameraTestPageState createState() => _CameraTestPageState();
}
class _CameraTestPageState extends State<CameraTestPage> {
List<CameraDescription>? cameras;
CameraController? controller;
bool frontCamera = false;
XFile? videoFile;
VideoPlayerController? videoController;
VoidCallback? videoPlayerListener;
@override
void initState() {
initCamera();
super.initState();
}
initCamera() async {
if (cameras == null) {
cameras = await availableCameras();
}
if (controller?.value.isInitialized ?? false) {
controller!.dispose();
}
controller = CameraController(
cameras!.firstWhere(
(element) => element.lensDirection == (frontCamera ? CameraLensDirection.front : CameraLensDirection.back),
),
ResolutionPreset.medium,
enableAudio: false,
);
controller!.initialize().then((value) {
setState(() {});
});
}
void onVideoRecordButtonPressed() {
startVideoRecording().then((_) {
if (mounted) setState(() {});
});
}
void onStopButtonPressed() {
stopVideoRecording().then((file) {
if (mounted) setState(() {});
if (file != null) {
print('Video recorded to ${file.path}');
videoFile = file;
_startVideoPlayer();
}
});
}
Future<void> _startVideoPlayer() async {
if (videoFile == null) {
return;
}
final VideoPlayerController vController = VideoPlayerController.file(File(videoFile!.path));
videoPlayerListener = () {
if (videoController != null && videoController!.value.size != null) {
// Refreshing the state to update video player with the correct ratio.
if (mounted) setState(() {});
videoController!.removeListener(videoPlayerListener!);
}
};
vController.addListener(videoPlayerListener!);
await vController.setLooping(true);
await vController.initialize();
await videoController?.dispose();
if (mounted) {
setState(() {
videoController = vController;
});
}
await vController.play();
}
Future<void> startVideoRecording() async {
final CameraController? cameraController = controller;
if (cameraController == null || !cameraController.value.isInitialized) {
print('Error: select a camera first.');
return;
}
if (cameraController.value.isRecordingVideo) {
// A recording is already started, do nothing.
return;
}
try {
await cameraController.startVideoRecording();
} on CameraException catch (e) {
_showCameraException(e);
return;
}
}
Future<XFile?> stopVideoRecording() async {
final CameraController? cameraController = controller;
if (cameraController == null || !cameraController.value.isRecordingVideo) {
return null;
}
try {
return cameraController.stopVideoRecording();
} on CameraException catch (e) {
_showCameraException(e);
return null;
}
}
void _showCameraException(CameraException e) {
print('Error: ${e.code}n${e.description}');
}
_uploadVideo() async {
Reference ref = FirebaseStorage.instance.ref("test/test.mov");
UploadTask uploadTask = ref.putFile(File(videoFile!.path), SettableMetadata(contentType: 'video/mov'));
print("uploading");
uploadTask.whenComplete(() async {
String downloadUrl = await ref.getDownloadURL();
print("download url: $downloadUrl");
});
}
Widget _thumbnailWidget() {
final VideoPlayerController? localVideoController = videoController;
return Expanded(
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
SizedBox(
child: (localVideoController == null)
? Center(
child: Container(
child: Text("none"),
),
)
: Container(
child: AspectRatio(
aspectRatio: localVideoController.value.aspectRatio,
child: VideoPlayer(localVideoController),
),
decoration: BoxDecoration(
border: Border.all(color: Colors.pink),
),
),
),
],
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Camera Test")),
body: Column(
children: [
if (controller != null)
Container(
child: CameraPreview(controller!),
height: 400,
),
Row(
children: [
ElevatedButton(
onPressed: () {
frontCamera = !frontCamera;
initCamera();
},
child: Text("Switch"),
),
ElevatedButton(
onPressed: () {
controller?.value.isRecordingVideo ?? false ? onStopButtonPressed() : onVideoRecordButtonPressed();
},
child: Text(controller?.value.isRecordingVideo ?? false ? "Stop" : "Record"),
),
ElevatedButton(
onPressed: videoFile != null ? _uploadVideo : null,
child: Text("Upload video"),
),
],
),
_thumbnailWidget(),
],
),
);
}
}

您可以使用video_compress包将视频转换为mp4。

这是您更新的_uploadVideo()方法,包括以下内容:

_uploadVideo() async {
Reference ref = FirebaseStorage.instance.ref("test/test.mp4");

MediaInfo? mediaInfo = await VideoCompress.compressVideo(
videoFile!.path,
quality: VideoQuality.DefaultQuality,
deleteOrigin: false, // It's false by default
);

UploadTask uploadTask = ref.putFile(
File(mediaInfo!.path!), SettableMetadata(contentType: 'video/mp4'));
print("uploading");

uploadTask.whenComplete(() async {
String downloadUrl = await ref.getDownloadURL();
print("download url: $downloadUrl");
});
}

确保您通过包含以下行导入包:

import 'package:video_compress/video_compress.dart';

最新更新