opus_flutter 1.0.1

Flutter Android iOS

libopus wrappers for flutter based on opus_dart, but with Android and iOS opus binaries included.


import 'dart:convert';
import 'dart:io';
import 'dart:math' show min;
import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:flutter_share/flutter_share.dart';
import 'package:opus_flutter/opus_dart.dart';
import 'package:path_provider/path_provider.dart';

void main() {

/// Even if we could load the file as whole, we create a stream out of it
/// to simulate streaming behaviour (e.g. if the stream comes over the network).
Stream<List<int>> exampleRawStream(BuildContext context) async* {
  const int portionSize =
      65535; //equals the usual size you get per list in a network stream
  ByteData data = await DefaultAssetBundle.of(context)
  int i = 0;
  while (i != data.lengthInBytes) {
    int r = min(portionSize, data.lengthInBytes - i);
    yield data.buffer.asUint8List(data.offsetInBytes + i, r);
    i += r;
    await new Future.delayed(
        const Duration(milliseconds: 10)); //Simulate network latency

class OpusFlutter extends StatelessWidget {
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('opus_flutter'),
        body: Center(
            child: Column(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: <Widget>[
              Text('Version: ${getOpusVersion()}\n'),

class OpusExample extends StatefulWidget {
  _OpusExampleState createState() => _OpusExampleState();

class _OpusExampleState extends State<OpusExample> {
  bool _processing;

  void initState() {
    _processing = false;

  Widget build(BuildContext context) {
    if (_processing) {
      return Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        children: <Widget>[
          Container(child: CircularProgressIndicator()),
    } else {
      return RaisedButton(
        onPressed: () {
          setState(() {
            _processing = true;
          example(exampleRawStream(context)).then((File f) {
            setState(() {
              _processing = false;
        child: const Text('Start'),

  Future<void> _playFile(File f) async {
    await FlutterShare.shareFile(
        title: 'Play',
        filePath: f.path,
        text: 'Choose an audio app to play the output file.');

/// This is mostly the same example as from the opus_dart package:
/// Get a stream, encode it and decode it, then save it to the harddrive.
/// Add a wav header, so it can be played by any sound app.
Future<File> example(Stream<List<int>> input) async {
  const int sampleRate = 16000;
  const int channels = 1;
  File file = new File((await getTemporaryDirectory()).path + '/output.wav');
  IOSink output = file.openWrite();
  output.add(new Uint8List(wavHeaderSize)); //Reserve space for the header
  //Encode and decode using opus
  await input
      .transform(new StreamOpusEncoder.bytes(
          floatInput: false,
          frameTime: FrameTime.ms20,
          sampleRate: sampleRate,
          channels: channels,
          application: Application.audio,
          copyOutput: true,
          fillUpLastFrame: true))
      .transform(new StreamOpusDecoder.bytes(
          floatOutput: false,
          sampleRate: sampleRate,
          channels: channels,
          copyOutput: true,
          forwardErrorCorrection: false))
  await output.close();
  //Write the wav header
  RandomAccessFile r = await file.open(mode: FileMode.append);
  await r.setPosition(0);
  await r.writeFrom(wavHeader(
      channels: channels,
      sampleRate: sampleRate,
      fileSize: await file.length()));
  await r.close();
  return file;

const int wavHeaderSize = 44;

Uint8List wavHeader({int sampleRate, int channels, int fileSize}) {
  const int sampleBits = 16; //We know this since we used opus
  const Endian endian = Endian.little;
  final int frameSize = ((sampleBits + 7) ~/ 8) * channels;
  ByteData data = new ByteData(wavHeaderSize);
  data.setUint32(4, fileSize - 4, endian);
  data.setUint32(16, 16, endian);
  data.setUint16(20, 1, endian);
  data.setUint16(22, channels, endian);
  data.setUint32(24, sampleRate, endian);
  data.setUint32(28, sampleRate * frameSize, endian);
  data.setUint16(30, frameSize, endian);
  data.setUint16(34, sampleBits, endian);
  data.setUint32(40, fileSize - 44, endian);
  Uint8List bytes = data.buffer.asUint8List();
  bytes.setAll(0, ascii.encode('RIFF'));
  bytes.setAll(8, ascii.encode('WAVE'));
  bytes.setAll(12, ascii.encode('fmt '));
  bytes.setAll(36, ascii.encode('data'));
  return bytes;
pub points

libopus wrappers for flutter based on opus_dart, but with Android and iOS opus binaries included.

Repository (GitHub)
View/report issues


API reference






flutter, opus_dart


Packages that depend on opus_flutter