我想实现instagram故事之类的功能(仅覆盖文字)。
我可以说用户可以在视频上添加一些文本,例如下面的屏幕截图(右上方的图标开始输入文本,左上方返回到上一页)。
用户输入一些文字后,我要将视频存储到Firebase storage
中。
但是问题是如何将这段文字保留在视频中?
有什么办法可以重写用户放置了文本叠加层的文件(重新编码)?
还是我必须将文本信息存储到数据库中然后提取并每次显示?
答案 0 :(得分:0)
我只能给出部分答案,希望对您有帮助。
您可以使用PictureRecorder
在Flutter中导出Canvas
的位图或png。
png图像的大小应与源视频的大小相同,您可以使用简单的Image
小部件将其覆盖在视频上。
您还可以将此png图像上传到Firebase,然后将其下载到其他客户端上以获得完全相同的外观(即使未安装字体时也是如此)。
很棒的事情是,您甚至可以在png图像中保存手绘图,贴纸,渐变和复杂形状(可以在画布上绘制的所有内容)之类的东西。
我想您也可以使用某种本机库将png图像烘焙到视频中。
这是一个简单的示例,展示了如何生成和显示这样的png图像:
import 'dart:async';
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
/// @param size Video size
/// @param text Styled text
ui.Image createTextImage(Size size, TextSpan text) {
final recorder = ui.PictureRecorder();
final cullRect = Offset.zero & size;
final canvas = Canvas(recorder, cullRect);
final textPainter = TextPainter(textDirection: TextDirection.ltr, text: text);
textPainter.layout();
// draw text in center of canvas, you can adjust this as you like
final textOffset = cullRect.center.translate(-textPainter.width / 2, textPainter.height / 2);
textPainter.paint(canvas, textOffset);
// you can also draw other geometrical shapes, gradients, paths...
canvas.drawCircle(Offset(100.0, 100.0), 50.0, Paint()..color = Color(0xffff00ff));
final picture = recorder.endRecording();
final image = picture.toImage(size.width.toInt(), size.height.toInt());
return image;
}
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Canvas Test',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
/// Bytes of the generated image
Future<Uint8List> _imageBytes;
_generateImage() {
// Get this size from your video
final videoSize = Size(720.0, 1280.0);
final textStyle = TextStyle(
fontFamily: 'Roboto',
fontSize: 80.0,
color: Colors.red,
);
final text = TextSpan(text: 'Hello World', style: textStyle);
// Generate the image
final imageInfo = createTextImage(videoSize, text);
// Convert to png
final imageBytes =
imageInfo.toByteData(format: ui.ImageByteFormat.png).then((byteData) => Uint8List.view(byteData.buffer));
setState(() {
_imageBytes = imageBytes;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Canvas Test'),
),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
FutureBuilder(
future: _imageBytes,
builder: (BuildContext context, AsyncSnapshot<Uint8List> snapshot) {
if (!snapshot.hasData) return Text('No data');
// Display the generated image in a box
return DecoratedBox(
decoration: BoxDecoration(border: Border.all()),
child: Image.memory(
snapshot.data,
width: 180.0,
height: 320.0,
),
);
},
),
RaisedButton(onPressed: _generateImage, child: Text('Generate Image'))
],
),
),
);
}
}
答案 1 :(得分:0)
也许不是一个完整的答案,因为我相信您必须自己动手才能使其正常工作。
因此,我面临着类似的情况,我需要在录制的视频中添加一些叠加层内容。
我遇到了这个包裹https://github.com/tanersener/flutter-ffmpeg
如果您查看有关ffmpeg的一些信息,则会发现它包含一些视频和音频处理工具。
我还没有尝试过,但是我会尽快开始,并以任何方法为您更新。 如果可能的话,我可能会为其编写一个程序包,以便可以轻松地将叠加层添加到视频中。
如果您发现其他问题,请告诉我