颤振如何在视频上保存(重新编码)文本叠加

时间:2018-08-15 03:46:20

标签: flutter overlay encode

我想实现instagram故事之类的功能(仅覆盖文字)。 我可以说用户可以在视频上添加一些文本,例如下面的屏幕截图(右上方的图标开始输入文本,左上方返回到上一页)。 用户输入一些文字后,我要将视频存储到Firebase storage中。 但是问题是如何将这段文字保留在视频中? 有什么办法可以重写用户放置了文本叠加层的文件(重新编码)? 还是我必须将文本信息存储到数据库中然后提取并每次显示?

enter image description here

2 个答案:

答案 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的一些信息,则会发现它包含一些视频和音频处理工具。

我还没有尝试过,但是我会尽快开始,并以任何方法为您更新。 如果可能的话,我可能会为其编写一个程序包,以便可以轻松地将叠加层添加到视频中。

如果您发现其他问题,请告诉我