Compare commits

...

2 Commits

Author SHA1 Message Date
Sarah Jamie Lewis f8a9b2c67f MiniAudio Wrapper - Playing Sounds 2024-02-11 18:43:01 -08:00
Sarah Jamie Lewis 15e4793ba8 First Cut 2024-02-11 15:14:33 -08:00
36 changed files with 94028 additions and 19 deletions

BIN
assets/sounds_online.wav Normal file

Binary file not shown.

View File

@ -4,11 +4,13 @@ import 'package:cwtch/main.dart';
import 'package:cwtch/models/appstate.dart';
import 'package:cwtch/models/contact.dart';
import 'package:cwtch/models/message.dart';
import 'package:cwtch/models/messages/VidMessage.dart';
import 'package:cwtch/models/profilelist.dart';
import 'package:cwtch/models/profileservers.dart';
import 'package:cwtch/models/remoteserver.dart';
import 'package:cwtch/models/servers.dart';
import 'package:cwtch/notification_manager.dart';
import 'package:cwtch/views/vidchatview.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:provider/provider.dart';
@ -187,6 +189,24 @@ class CwtchNotifier {
break;
case "NewMessageFromPeer":
var identifier = int.parse(data["ConversationID"]);
dynamic message = jsonDecode(data["Data"]);
var overlay = int.parse(message['o'].toString());
if (overlay == VideoOverlay) {
try {
VidMessage vmsg = VidMessage.fromJson(message);
EnvironmentConfig.debugLog("send latency = ${DateTime.now().toUtc().difference(vmsg.s ?? DateTime.now()).inMilliseconds}");
EnvironmentConfig.debugLog("tor latency = ${DateTime.now().toUtc().difference(vmsg.t ?? DateTime.now()).inMilliseconds}");
EnvironmentConfig.debugLog("recv latency = ${DateTime.now().toUtc().difference(vmsg.r ?? DateTime.now()).inMilliseconds}");
profileCN.getProfile(data["ProfileOnion"])!.contactList.getContact(identifier)!.vid = vmsg.d;
} catch (e) {
EnvironmentConfig.debugLog("error decoding video stream: $e: ${message['d']}");
}
break;
}
var messageID = int.parse(data["Index"]);
var timestamp = DateTime.tryParse(data['TimestampReceived'])!;
var senderHandle = data['RemotePeer'];

View File

@ -648,4 +648,20 @@ class MaterialLocalizationLu extends MaterialLocalizations {
@override
// TODO: implement scanTextButtonLabel
String get scanTextButtonLabel => throw UnimplementedError();
@override
// TODO: implement lookUpButtonLabel
String get lookUpButtonLabel => throw UnimplementedError();
@override
// TODO: implement menuDismissLabel
String get menuDismissLabel => throw UnimplementedError();
@override
// TODO: implement searchWebButtonLabel
String get searchWebButtonLabel => throw UnimplementedError();
@override
// TODO: implement shareButtonLabel
String get shareButtonLabel => throw UnimplementedError();
}

View File

@ -2,6 +2,7 @@ import 'dart:async';
import 'dart:io';
import 'package:cwtch/config.dart';
import 'package:cwtch/third_party/miniaudio/lib/miniaudio.dart';
import 'package:flutter/widgets.dart';
enum ModalState { none, storageMigration, shutdown }
@ -28,6 +29,10 @@ class AppState extends ChangeNotifier {
void SetCwtchInit() {
cwtchInit = true;
var audio = MiniAudio();
audio.initAudio().then((value) {
audio.playAudio("assets/sounds_online.wav");
});
notifyListeners();
}

View File

@ -1,5 +1,7 @@
import 'dart:convert';
import 'dart:ffi';
import 'package:cwtch/config.dart';
import 'package:cwtch/main.dart';
import 'package:cwtch/models/message_draft.dart';
import 'package:cwtch/models/profile.dart';
@ -7,6 +9,7 @@ import 'package:cwtch/models/redaction.dart';
import 'package:cwtch/themes/opaque.dart';
import 'package:cwtch/views/contactsview.dart';
import 'package:cwtch/widgets/messagerow.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
@ -133,6 +136,14 @@ class ContactInfoState extends ChangeNotifier {
MessageDraft get messageDraft => this._messageDraft;
DateTime get lastRetryTime => this._lastRetryTime;
Uint8List _vid = Uint8List(0);
Uint8List get vid => _vid;
set vid(data) {
this._vid = data;
notifyListeners();
}
set lastRetryTime(DateTime lastRetryTime) {
this._lastRetryTime = lastRetryTime;
notifyListeners();

View File

@ -20,7 +20,7 @@ const QuotedMessageOverlay = 10;
const SuggestContactOverlay = 100;
const InviteGroupOverlay = 101;
const FileShareOverlay = 200;
const VideoOverlay = 0xF07;
// Defines the length of the tor v3 onion address. Code using this constant will
// need to updated when we allow multiple different identifiers. At which time
// it will likely be prudent to define a proper Contact wrapper.

View File

@ -0,0 +1,23 @@
import 'package:cwtch/third_party/base85/base_85_encoder.dart';
import 'package:flutter/foundation.dart';
import '../../third_party/base85/base_85_codec.dart';
class VidMessage {
final int o;
final Uint8List d;
DateTime? s;
DateTime? r;
DateTime? t;
VidMessage({required this.o, required this.d});
VidMessage.fromJson(Map<String, dynamic> json)
: o = json['o'],
d = Base85Codec.new().decode(json['d']),
s = DateTime.tryParse(json['s'] ?? ""),
t = DateTime.tryParse(json['t'] ?? ""),
r = DateTime.tryParse(json['r'] ?? "");
Map<String, dynamic> toJson() => {'o': o, 'd': Base85Codec.new().encode(d), 's': DateTime.now().toUtc().toIso8601String()};
}

1
lib/third_party/base85 vendored Submodule

@ -0,0 +1 @@
Subproject commit 51d8c18dd869702fbef77ce574493078a2acf54d

View File

@ -0,0 +1,31 @@
## 0.0.1
* Initial release.
## 0.0.2
* Fixes in core API.
## 0.0.3
* Created API for storing frame into Base64 Image.
## 0.0.4
* Code refractor
## 0.0.5
* Converted API functions into asyc functions.
## 0.0.6
* Dart SDK version changed to 3.1.0
## 0.0.7
* OpenCV Dependencies added statically
## 0.0.8
* OpenCV static dependencies removed

60
lib/third_party/camera_linux/LICENSE vendored Normal file
View File

@ -0,0 +1,60 @@
BSD 3-Clause License
Copyright (c) 2023, Open Privacy Research Society
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----
Original License Follows...
BSD 3-Clause License
Copyright (c) 2023, Muhammad Islam
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

93
lib/third_party/camera_linux/README.md vendored Normal file
View File

@ -0,0 +1,93 @@
# camera_linux
Camera Linux is a Flutter FFI plugin designed specifically for the Linux platform. This plugin allows Flutter developers to access and capture images from the Linux camera, seamlessly integrating native code invocation using Dart's FFI.
## Getting Started
Dart FFI Integration: Built on top of Flutter's FFI (Foreign Function Interface) to directly invoke native functions.
Platform-Specific: Tailored for Linux, ensuring optimal performance and compatibility.
Easy Access to Camera: Provides straightforward functions to capture images directly from the Linux camera.
## Project structure
This template uses the following structure:
* `src`: Contains the native source code, and a CmakeFile.txt file for building
that source code into a dynamic library.
* `lib`: Contains the Dart code that defines the API of the plugin, and which
calls into the native code using `dart:ffi`.
* platform folder (`linux`): Contains the build files
for building and bundling the native code library with the platform application.
## Building and bundling native code
The `pubspec.yaml` specifies FFI plugins as follows:
```yaml
plugin:
platforms:
some_platform:
ffiPlugin: true
```
This configuration invokes the native build for the various target platforms
and bundles the binaries in Flutter applications using these FFI plugins.
This can be combined with dartPluginClass, such as when FFI is used for the
implementation of one platform in a federated plugin:
```yaml
plugin:
implements: some_other_plugin
platforms:
some_platform:
dartPluginClass: SomeClass
ffiPlugin: true
```
A plugin can have both FFI and method channels:
```yaml
plugin:
platforms:
some_platform:
pluginClass: SomeName
ffiPlugin: true
```
The native build systems that are invoked by FFI (and method channel) plugin is:
* For Linux and Windows: CMake.
* See the documentation in linux/CMakeLists.txt.
* See the documentation in windows/CMakeLists.txt.
## Binding to native code
Instead of manually writing the Dart bindings to native code, they are auto-generated from the header file (src/camera_linux.h) using the package:ffigen. To refresh these bindings, execute:
`flutter pub run ffigen --config ffigen.yaml`
## Invoking native code
Very short-running native functions can be directly invoked from any isolate.
For example, see `sum` in `lib/camera_linux.dart`.
Longer-running functions should be invoked on a helper isolate to avoid
dropping frames in Flutter applications.
For example, see `sumAsync` in `lib/camera_linux.dart`.
## Getting Started with the Plugin
Add the camera_linux plugin to your pubspec.yaml:
```dependencies:
camera_linux: ^0.1.0
```
Execute the following command to fetch the package:
`flutter pub get`
## Further Assistance
For comprehensive guidance on Flutter, visit the official documentation, offering tutorials, samples, mobile development insights, and a complete API reference.

View File

@ -0,0 +1,19 @@
# Run with `flutter pub run ffigen --config ffigen.yaml`.
name: CameraLinuxBindings
description: |
Bindings for `src/camera_linux.h`.
Regenerate bindings with `flutter pub run ffigen --config ffigen.yaml`.
output: 'lib/camera_linux_bindings_generated.dart'
headers:
entry-points:
- 'src/camera_linux.h'
include-directives:
- 'src/camera_linux.h'
preamble: |
// ignore_for_file: always_specify_types
// ignore_for_file: camel_case_types
// ignore_for_file: non_constant_identifier_names
comments:
style: any
length: full

View File

@ -0,0 +1,38 @@
import 'dart:async';
import 'dart:ffi';
import 'dart:typed_data';
import 'camera_linux_bindings_generated.dart';
import 'package:ffi/ffi.dart';
class CameraLinux {
late CameraLinuxBindings _bindings;
CameraLinux() {
final dylib = DynamicLibrary.open('libcamera_linux.so');
_bindings = CameraLinuxBindings(dylib);
}
// Open Default Camera
Future<void> initializeCamera() async {
_bindings.startVideoCaptureInThread();
}
// Close The Camera
void stopCamera() {
_bindings.stopVideoCapture();
}
// Capture The Frame
Future<Uint8List> captureImage() async {
final lengthPtr = calloc<Int>();
Pointer<Uint8> framePointer = _bindings.getLatestFrameBytes(lengthPtr);
final latestFrame = getLatestFrameData(framePointer, lengthPtr.value);
return latestFrame;
}
// Get The Latest Frame
Uint8List getLatestFrameData(Pointer<Uint8> framePointer, frameSize) {
List<int> frameList = framePointer.asTypedList(frameSize);
return Uint8List.fromList(frameList);
}
}

View File

@ -0,0 +1,48 @@
// ignore_for_file: always_specify_types
// ignore_for_file: camel_case_types
// ignore_for_file: non_constant_identifier_names
// AUTO GENERATED FILE, DO NOT EDIT.
//
// Generated by `package:ffigen`.
import 'dart:ffi' as ffi;
/// Bindings for `src/camera_linux.h`.
///
/// Regenerate bindings with `flutter pub run ffigen --config ffigen.yaml`.
///
class CameraLinuxBindings {
/// Holds the symbol lookup function.
final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName) _lookup;
/// The symbols are looked up in [dynamicLibrary].
CameraLinuxBindings(ffi.DynamicLibrary dynamicLibrary) : _lookup = dynamicLibrary.lookup;
/// The symbols are looked up with [lookup].
CameraLinuxBindings.fromLookup(ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName) lookup) : _lookup = lookup;
void startVideoCaptureInThread() {
return _startVideoCaptureInThread();
}
late final _startVideoCaptureInThreadPtr = _lookup<ffi.NativeFunction<ffi.Void Function()>>('startVideoCaptureInThread');
late final _startVideoCaptureInThread = _startVideoCaptureInThreadPtr.asFunction<void Function()>();
void stopVideoCapture() {
return _stopVideoCapture();
}
late final _stopVideoCapturePtr = _lookup<ffi.NativeFunction<ffi.Void Function()>>('stopVideoCapture');
late final _stopVideoCapture = _stopVideoCapturePtr.asFunction<void Function()>();
ffi.Pointer<ffi.Uint8> getLatestFrameBytes(
ffi.Pointer<ffi.Int> length,
) {
return _getLatestFrameBytes(
length,
);
}
late final _getLatestFrameBytesPtr = _lookup<ffi.NativeFunction<ffi.Pointer<ffi.Uint8> Function(ffi.Pointer<ffi.Int>)>>('getLatestFrameBytes');
late final _getLatestFrameBytes = _getLatestFrameBytesPtr.asFunction<ffi.Pointer<ffi.Uint8> Function(ffi.Pointer<ffi.Int>)>();
}

View File

@ -0,0 +1,22 @@
# The Flutter tooling requires that developers have CMake 3.10 or later
# installed. You should not increase this version, as doing so will cause
# the plugin to fail to compile for some customers of the plugin.
cmake_minimum_required(VERSION 3.10)
# Project-level configuration.
set(PROJECT_NAME "camera_linux")
project(${PROJECT_NAME} LANGUAGES CXX)
# Invoke the build for native code shared with the other target platforms.
# This can be changed to accommodate different builds.
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../src" "${CMAKE_CURRENT_BINARY_DIR}/shared")
# List of absolute paths to libraries that should be bundled with the plugin.
# This list could contain prebuilt libraries, or libraries created by an
# external build triggered from this build file.
set(camera_linux_bundled_libraries
# Defined in ../src/CMakeLists.txt.
# This can be changed to accommodate different builds.
$<TARGET_FILE:camera_linux>
PARENT_SCOPE
)

View File

@ -0,0 +1,73 @@
name: camera_linux
description: Take pictures from camere on linux platform.
version: 0.0.8
homepage: https://github.com/islamroshan/camera-linux.git
environment:
sdk: '>=3.1.0 <4.0.0'
flutter: '>=3.3.0'
dependencies:
flutter:
sdk: flutter
plugin_platform_interface: ^2.0.2
ffi: ^2.0.1
dev_dependencies:
ffigen: 11.0.0
flutter_test:
sdk: flutter
flutter_lints: ^2.0.0
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter packages.
flutter:
# This section identifies this Flutter project as a plugin project.
# The 'pluginClass' specifies the class (in Java, Kotlin, Swift, Objective-C, etc.)
# which should be registered in the plugin registry. This is required for
# using method channels.
# The Android 'package' specifies package in which the registered class is.
# This is required for using method channels on Android.
# The 'ffiPlugin' specifies that native code should be built and bundled.
# This is required for using `dart:ffi`.
# All these are used by the tooling to maintain consistency when
# adding or updating assets for this project.
#
# Please refer to README.md for a detailed explanation.
plugin:
platforms:
linux:
ffiPlugin: true
# To add assets to your plugin package, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
#
# For details regarding assets in packages, see
# https://flutter.dev/assets-and-images/#from-packages
#
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware
# To add custom fonts to your plugin package, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts in packages, see
# https://flutter.dev/custom-fonts/#from-packages

View File

@ -0,0 +1,20 @@
cmake_minimum_required(VERSION 3.10)
project(camera_linux_library VERSION 0.0.1 LANGUAGES C CXX)
set(SOURCE_FILES opencv_wrapper.cpp)
add_library(opencv_wrapper SHARED ${SOURCE_FILES})
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
target_link_libraries(opencv_wrapper ${OpenCV_LIBS})
add_library(camera_linux SHARED "camera_linux.c")
target_link_libraries(camera_linux opencv_wrapper)
set_target_properties(camera_linux PROPERTIES
PUBLIC_HEADER camera_linux.h
OUTPUT_NAME "camera_linux"
)
target_compile_definitions(camera_linux PUBLIC DART_SHARED_LIB)

View File

@ -0,0 +1,5 @@
#include "camera_linux.h"
void startVideoCaptureInThread();
void stopVideoCapture();

View File

@ -0,0 +1,15 @@
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
void startVideoCaptureInThread();
void stopVideoCapture();
uint8_t* getLatestFrameBytes(int* length);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,87 @@
#include <iostream>
#include <opencv2/opencv.hpp>
#include <thread>
#include <atomic>
using namespace std;
using namespace cv;
std::thread videoThread;
std::atomic<bool> stopFlag(false);
Mat latestFrame;
// Extern C block to expose the function to C
extern "C" {
// Function to capture video frames
void runVideoCapture() {
VideoCapture cap;
int deviceID = 0; // 0 = open default camera
int apiID = cv::CAP_ANY; // 0 = autodetect default API
cap.open(deviceID, apiID);
cap.set(cv::CAP_PROP_FRAME_WIDTH, 160);
cap.set(cv::CAP_PROP_FRAME_HEIGHT, 120);
if (!cap.isOpened()) {
cerr << "ERROR! Unable to open camera\n";
return ;
}
while (!stopFlag.load()) {
cap >> latestFrame;
if (latestFrame.empty()) {
break;
}
}
cap.release();
}
void startVideoCaptureInThread() {
stopFlag = false;
videoThread = std::thread(runVideoCapture);
videoThread.detach();
}
void stopVideoCapture() {
stopFlag = true;
if (videoThread.joinable()) {
videoThread.join();
}
}
uint8_t* getLatestFrameBytes(int* length) {
// Ensure the pointer is valid
if (!length) {
return nullptr;
}
*length = 0; // Initialize length to 0
if (latestFrame.empty()) {
return nullptr;
}
vector<int> compression_params;
compression_params.push_back(IMWRITE_JPEG_QUALITY);
compression_params.push_back(50);
// Encode the frame as JPEG
vector<uint8_t> buf;
bool encodeSuccess = imencode(".jpg", latestFrame, buf, compression_params );
// Check if encoding was successful
if (!encodeSuccess || buf.empty()) {
return nullptr;
}
*length = static_cast<int>(buf.size());
cout << buf.size() << endl;
// Allocate memory and copy data
uint8_t* data = new uint8_t[(*length)];
if (!data) {
cout << "Memory allocation failed." << endl;
return nullptr;
}
memcpy(data, buf.data(), *length);
return data;
}
}

19
lib/third_party/miniaudio/ffigen.yaml vendored Normal file
View File

@ -0,0 +1,19 @@
# Run with `flutter pub run ffigen --config ffigen.yaml`.
name: MiniAudioBindings
description: |
Bindings for `src/audio.h`.
Regenerate bindings with `flutter pub run ffigen --config ffigen.yaml`.
output: 'lib/miniaudio_bindings_generated.dart'
headers:
entry-points:
- 'src/audio.h'
include-directives:
- 'src/audio.h'
preamble: |
// ignore_for_file: always_specify_types
// ignore_for_file: camel_case_types
// ignore_for_file: non_constant_identifier_names
comments:
style: any
length: full

View File

@ -0,0 +1,27 @@
import 'dart:async';
import 'dart:ffi';
import 'dart:typed_data';
import 'package:miniaudio/miniaudio_bindings_generated.dart';
import 'package:ffi/ffi.dart';
class MiniAudio {
late MiniAudioBindings _bindings;
MiniAudio() {
final dylib = DynamicLibrary.open('libminiaudio.so');
_bindings = MiniAudioBindings(dylib);
}
Future<void> initAudio() async {
_bindings.initAudio();
}
// Open Default Camera
Future<void> playAudio(String file) async {
var filePtr = file.toNativeUtf8();
_bindings.playAudio(filePtr.cast());
malloc.free(filePtr);
}
}

View File

@ -0,0 +1,50 @@
// ignore_for_file: always_specify_types
// ignore_for_file: camel_case_types
// ignore_for_file: non_constant_identifier_names
// AUTO GENERATED FILE, DO NOT EDIT.
//
// Generated by `package:ffigen`.
import 'dart:ffi' as ffi;
/// Bindings for `src/audio.h`.
///
/// Regenerate bindings with `flutter pub run ffigen --config ffigen.yaml`.
///
class MiniAudioBindings {
/// Holds the symbol lookup function.
final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
_lookup;
/// The symbols are looked up in [dynamicLibrary].
MiniAudioBindings(ffi.DynamicLibrary dynamicLibrary)
: _lookup = dynamicLibrary.lookup;
/// The symbols are looked up with [lookup].
MiniAudioBindings.fromLookup(
ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
lookup)
: _lookup = lookup;
void initAudio() {
return _initAudio();
}
late final _initAudioPtr =
_lookup<ffi.NativeFunction<ffi.Void Function()>>('initAudio');
late final _initAudio = _initAudioPtr.asFunction<void Function()>();
void playAudio(
ffi.Pointer<ffi.Char> file,
) {
return _playAudio(
file,
);
}
late final _playAudioPtr =
_lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Char>)>>(
'playAudio');
late final _playAudio =
_playAudioPtr.asFunction<void Function(ffi.Pointer<ffi.Char>)>();
}

View File

@ -0,0 +1,22 @@
# The Flutter tooling requires that developers have CMake 3.10 or later
# installed. You should not increase this version, as doing so will cause
# the plugin to fail to compile for some customers of the plugin.
cmake_minimum_required(VERSION 3.10)
# Project-level configuration.
set(PROJECT_NAME "miniaudio")
project(${PROJECT_NAME} LANGUAGES CXX)
# Invoke the build for native code shared with the other target platforms.
# This can be changed to accommodate different builds.
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../src" "${CMAKE_CURRENT_BINARY_DIR}/shared")
# List of absolute paths to libraries that should be bundled with the plugin.
# This list could contain prebuilt libraries, or libraries created by an
# external build triggered from this build file.
set(miniaudio_bundled_libraries
# Defined in ../src/CMakeLists.txt.
# This can be changed to accommodate different builds.
$<TARGET_FILE:miniaudio>
PARENT_SCOPE
)

333
lib/third_party/miniaudio/pubspec.lock vendored Normal file
View File

@ -0,0 +1,333 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
archive:
dependency: transitive
description:
name: archive
sha256: "22600aa1e926be775fa5fe7e6894e7fb3df9efda8891c73f70fb3262399a432d"
url: "https://pub.dev"
source: hosted
version: "3.4.10"
args:
dependency: transitive
description:
name: args
sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596
url: "https://pub.dev"
source: hosted
version: "2.4.2"
async:
dependency: transitive
description:
name: async
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
url: "https://pub.dev"
source: hosted
version: "2.11.0"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
url: "https://pub.dev"
source: hosted
version: "2.1.1"
characters:
dependency: transitive
description:
name: characters
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
url: "https://pub.dev"
source: hosted
version: "1.3.0"
cli_util:
dependency: transitive
description:
name: cli_util
sha256: "66f86e916d285c1a93d3b79587d94bd71984a66aac4ff74e524cfa7877f1395c"
url: "https://pub.dev"
source: hosted
version: "0.3.5"
clock:
dependency: transitive
description:
name: clock
sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
url: "https://pub.dev"
source: hosted
version: "1.1.1"
collection:
dependency: transitive
description:
name: collection
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
url: "https://pub.dev"
source: hosted
version: "1.18.0"
convert:
dependency: transitive
description:
name: convert
sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
url: "https://pub.dev"
source: hosted
version: "3.1.1"
crypto:
dependency: transitive
description:
name: crypto
sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab
url: "https://pub.dev"
source: hosted
version: "3.0.3"
fake_async:
dependency: transitive
description:
name: fake_async
sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
url: "https://pub.dev"
source: hosted
version: "1.3.1"
ffi:
dependency: "direct main"
description:
name: ffi
sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
ffigen:
dependency: "direct dev"
description:
name: ffigen
sha256: ec6a2439159d27c871d92862fb9f3012ef19d9ec4b0fa383c69c8553b2dd2ac5
url: "https://pub.dev"
source: hosted
version: "6.1.2"
file:
dependency: transitive
description:
name: file
sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d"
url: "https://pub.dev"
source: hosted
version: "6.1.4"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_lints:
dependency: "direct dev"
description:
name: flutter_lints
sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04
url: "https://pub.dev"
source: hosted
version: "2.0.3"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
glob:
dependency: transitive
description:
name: glob
sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63"
url: "https://pub.dev"
source: hosted
version: "2.1.2"
image:
dependency: "direct dev"
description:
name: image
sha256: "8e9d133755c3e84c73288363e6343157c383a0c6c56fc51afcc5d4d7180306d6"
url: "https://pub.dev"
source: hosted
version: "3.3.0"
js:
dependency: transitive
description:
name: js
sha256: "4186c61b32f99e60f011f7160e32c89a758ae9b1d0c6d28e2c02ef0382300e2b"
url: "https://pub.dev"
source: hosted
version: "0.7.0"
lints:
dependency: transitive
description:
name: lints
sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452"
url: "https://pub.dev"
source: hosted
version: "2.1.1"
logging:
dependency: transitive
description:
name: logging
sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340"
url: "https://pub.dev"
source: hosted
version: "1.2.0"
matcher:
dependency: transitive
description:
name: matcher
sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
url: "https://pub.dev"
source: hosted
version: "0.12.16"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
url: "https://pub.dev"
source: hosted
version: "0.5.0"
meta:
dependency: transitive
description:
name: meta
sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e
url: "https://pub.dev"
source: hosted
version: "1.10.0"
path:
dependency: transitive
description:
name: path
sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
url: "https://pub.dev"
source: hosted
version: "1.8.3"
petitparser:
dependency: transitive
description:
name: petitparser
sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27
url: "https://pub.dev"
source: hosted
version: "6.0.2"
plugin_platform_interface:
dependency: "direct main"
description:
name: plugin_platform_interface
sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
url: "https://pub.dev"
source: hosted
version: "2.1.8"
pointycastle:
dependency: transitive
description:
name: pointycastle
sha256: "43ac87de6e10afabc85c445745a7b799e04de84cebaa4fd7bf55a5e1e9604d29"
url: "https://pub.dev"
source: hosted
version: "3.7.4"
quiver:
dependency: transitive
description:
name: quiver
sha256: b1c1ac5ce6688d77f65f3375a9abb9319b3cb32486bdc7a1e0fdf004d7ba4e47
url: "https://pub.dev"
source: hosted
version: "3.2.1"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
source_span:
dependency: transitive
description:
name: source_span
sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
url: "https://pub.dev"
source: hosted
version: "1.10.0"
stack_trace:
dependency: transitive
description:
name: stack_trace
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
url: "https://pub.dev"
source: hosted
version: "1.11.1"
stream_channel:
dependency: transitive
description:
name: stream_channel
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
url: "https://pub.dev"
source: hosted
version: "2.1.2"
string_scanner:
dependency: transitive
description:
name: string_scanner
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
url: "https://pub.dev"
source: hosted
version: "1.2.0"
term_glyph:
dependency: transitive
description:
name: term_glyph
sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
url: "https://pub.dev"
source: hosted
version: "1.2.1"
test_api:
dependency: transitive
description:
name: test_api
sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
url: "https://pub.dev"
source: hosted
version: "0.6.1"
typed_data:
dependency: transitive
description:
name: typed_data
sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
url: "https://pub.dev"
source: hosted
version: "1.3.2"
vector_math:
dependency: transitive
description:
name: vector_math
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
url: "https://pub.dev"
source: hosted
version: "2.1.4"
web:
dependency: transitive
description:
name: web
sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152
url: "https://pub.dev"
source: hosted
version: "0.3.0"
xml:
dependency: transitive
description:
name: xml
sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
url: "https://pub.dev"
source: hosted
version: "6.5.0"
yaml:
dependency: transitive
description:
name: yaml
sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5"
url: "https://pub.dev"
source: hosted
version: "3.1.2"
sdks:
dart: ">=3.2.0 <4.0.0"
flutter: ">=3.3.0"

73
lib/third_party/miniaudio/pubspec.yaml vendored Normal file
View File

@ -0,0 +1,73 @@
name: miniaudio
description: Play audio
version: 0.0.1
environment:
sdk: '>=3.1.0 <4.0.0'
flutter: '>=3.3.0'
dependencies:
flutter:
sdk: flutter
plugin_platform_interface: ^2.0.2
ffi: ^2.0.1
dev_dependencies:
ffigen: ^6.1.2
image: ^3.0.1
flutter_test:
sdk: flutter
flutter_lints: ^2.0.0
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter packages.
flutter:
# This section identifies this Flutter project as a plugin project.
# The 'pluginClass' specifies the class (in Java, Kotlin, Swift, Objective-C, etc.)
# which should be registered in the plugin registry. This is required for
# using method channels.
# The Android 'package' specifies package in which the registered class is.
# This is required for using method channels on Android.
# The 'ffiPlugin' specifies that native code should be built and bundled.
# This is required for using `dart:ffi`.
# All these are used by the tooling to maintain consistency when
# adding or updating assets for this project.
#
# Please refer to README.md for a detailed explanation.
plugin:
platforms:
linux:
ffiPlugin: true
# To add assets to your plugin package, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
#
# For details regarding assets in packages, see
# https://flutter.dev/assets-and-images/#from-packages
#
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware
# To add custom fonts to your plugin package, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts in packages, see
# https://flutter.dev/custom-fonts/#from-packages

View File

@ -0,0 +1,13 @@
cmake_minimum_required(VERSION 3.10)
project(audio_library VERSION 0.0.1 LANGUAGES C CXX)
add_library(miniaudio SHARED "audio.c")
target_link_libraries(miniaudio)
set_target_properties(miniaudio PROPERTIES
PUBLIC_HEADER audio.h
PUBLIC_HEADER miniaudio.h
OUTPUT_NAME "miniaudio"
)
target_compile_definitions(miniaudio PUBLIC DART_SHARED_LIB)

67
lib/third_party/miniaudio/src/audio.c vendored Normal file
View File

@ -0,0 +1,67 @@
#define MINIAUDIO_IMPLEMENTATION
#include "miniaudio.h"
#include <stdio.h>
ma_device recording_device;
ma_engine engine;
void initAudio() {
ma_result result;
result = ma_engine_init(NULL, &engine);
if (result != MA_SUCCESS) {
printf("Could not init engine\n");
}
}
void playAudio(char * file) {
ma_engine_play_sound(&engine, file, NULL);
}
void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount)
{
ma_encoder* pEncoder = (ma_encoder*)pDevice->pUserData;
MA_ASSERT(pEncoder != NULL);
ma_encoder_write_pcm_frames(pEncoder, pInput, frameCount, NULL);
(void)pOutput;
}
void startRecording() {
ma_result result;
ma_encoder_config encoderConfig;
ma_encoder encoder;
ma_device_config deviceConfig;
encoderConfig = ma_encoder_config_init(ma_encoding_format_wav, ma_format_f32, 2, 44100);
deviceConfig = ma_device_config_init(ma_device_type_capture);
deviceConfig.capture.format = encoder.config.format;
deviceConfig.capture.channels = encoder.config.channels;
deviceConfig.sampleRate = encoder.config.sampleRate;
deviceConfig.dataCallback = data_callback;
deviceConfig.pUserData = &encoder;
if (ma_encoder_init_file("test.wav", &encoderConfig, &encoder) != MA_SUCCESS) {
printf("Failed to initialize output file.\n");
return ;
}
result = ma_device_init(NULL, &deviceConfig, &recording_device);
if (result != MA_SUCCESS) {
printf("Failed to initialize capture device.\n");
return ;
}
result = ma_device_start(&recording_device);
if (result != MA_SUCCESS) {
printf("Failed to start device.\n");
return;
}
}
void stopRecording() {
ma_result result;
result = ma_device_stop(&recording_device);
}

14
lib/third_party/miniaudio/src/audio.h vendored Normal file
View File

@ -0,0 +1,14 @@
#include <stdint.h>
#include "miniaudio.h"
#ifdef __cplusplus
extern "C" {
#endif
void initAudio();
void playAudio(char * file);
#ifdef __cplusplus
}
#endif

92621
lib/third_party/miniaudio/src/miniaudio.h vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -15,6 +15,7 @@ import 'package:cwtch/models/messages/quotedmessage.dart';
import 'package:cwtch/models/profile.dart';
import 'package:cwtch/themes/opaque.dart';
import 'package:cwtch/third_party/linkify/flutter_linkify.dart';
import 'package:cwtch/views/vidchatview.dart';
import 'package:cwtch/widgets/malformedbubble.dart';
import 'package:cwtch/widgets/messageloadingbubble.dart';
import 'package:cwtch/widgets/profileimage.dart';
@ -102,6 +103,7 @@ class _MessageViewState extends State<MessageView> {
appBarButtons.add(IconButton(
splashRadius: Material.defaultSplashRadius / 2, icon: Icon(CwtchIcons.manage_files), tooltip: AppLocalizations.of(context)!.manageSharedFiles, onPressed: _pushFileSharingSettings));
}
appBarButtons.add(IconButton(splashRadius: Material.defaultSplashRadius / 2, icon: Icon(Icons.videocam), tooltip: AppLocalizations.of(context)!.manageSharedFiles, onPressed: _pushVidChat));
if (Provider.of<ContactInfoState>(context, listen: false).isOnline()) {
appBarButtons.add(IconButton(
@ -279,6 +281,23 @@ class _MessageViewState extends State<MessageView> {
return true;
}
void _pushVidChat() {
var profileInfoState = Provider.of<ProfileInfoState>(context, listen: false);
var contactInfoState = Provider.of<ContactInfoState>(context, listen: false);
Navigator.of(context).push(
PageRouteBuilder(
pageBuilder: (builderContext, a1, a2) {
return MultiProvider(
providers: [ChangeNotifierProvider.value(value: profileInfoState), ChangeNotifierProvider.value(value: contactInfoState)],
child: VidChatView(),
);
},
transitionsBuilder: (c, anim, a2, child) => FadeTransition(opacity: anim, child: child),
transitionDuration: Duration(milliseconds: 200),
),
);
}
void _pushFileSharingSettings() {
var profileInfoState = Provider.of<ProfileInfoState>(context, listen: false);
var contactInfoState = Provider.of<ContactInfoState>(context, listen: false);

View File

@ -0,0 +1,73 @@
import 'dart:convert';
import 'dart:ui';
import 'package:cwtch/config.dart';
import 'package:cwtch/cwtch_icons_icons.dart';
import 'package:cwtch/models/appstate.dart';
import 'package:cwtch/models/contact.dart';
import 'package:cwtch/widgets/camfeed.dart';
import 'package:cwtch/widgets/profileimage.dart';
import 'package:flutter/services.dart';
import 'package:cwtch/widgets/buttontextfield.dart';
import 'package:cwtch/widgets/cwtchlabel.dart';
import 'package:flutter/material.dart';
import 'package:cwtch/settings.dart';
import 'package:provider/provider.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:camera_linux/camera_linux.dart';
import '../main.dart';
import '../themes/opaque.dart';
class VidChatView extends StatefulWidget {
@override
_VidChatViewState createState() => _VidChatViewState();
}
class _VidChatViewState extends State<VidChatView> {
final _cameraLinuxPlugin = CameraLinux();
bool _isCameraOpen = false;
late String _base64Image;
@override
void dispose() {
_cameraLinuxPlugin.stopCamera();
super.dispose();
}
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
var handle = Provider.of<ContactInfoState>(context).nickname;
if (handle.isEmpty) {
handle = Provider.of<ContactInfoState>(context).onion;
}
return Scaffold(
appBar: AppBar(
title: Container(
height: Provider.of<Settings>(context).fontScaling * 24.0,
clipBehavior: Clip.hardEdge,
decoration: BoxDecoration(),
child: Text(handle + " " + AppLocalizations.of(context)!.conversationSettings)),
),
body: _buildVidChat(),
);
}
Widget _buildVidChat() {
return Column(children: [
CameraFeed(_cameraLinuxPlugin),
Image.memory(
Provider.of<ContactInfoState>(context).vid,
width: 320,
height: 240,
gaplessPlayback: true,
errorBuilder: (context, error, stackTrace) {
EnvironmentConfig.debugLog("error ${Provider.of<ContactInfoState>(context).vid.length}");
return Container();
},
),
]);
}
}

71
lib/widgets/camfeed.dart Normal file
View File

@ -0,0 +1,71 @@
import 'package:cwtch/config.dart';
import 'package:cwtch/models/message.dart';
import 'package:cwtch/third_party/base85/base_85_codec.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:convert';
import 'package:camera_linux/camera_linux.dart';
import 'package:provider/provider.dart';
import '../main.dart';
import '../models/contact.dart';
import '../models/messages/VidMessage.dart';
class CameraFeed extends StatefulWidget {
final CameraLinux cameraLinuxPlugin;
CameraFeed(this.cameraLinuxPlugin, {super.key});
@override
State<CameraFeed> createState() => _CameraFeed();
}
class _CameraFeed extends State<CameraFeed> {
Uint8List _Image = Uint8List(0);
late Timer timer;
@override
void initState() {
super.initState();
_initializeCamera();
}
@override
void dispose() {
super.dispose();
timer.cancel();
}
// Open Default Camera
Future<void> _initializeCamera() async {
await widget.cameraLinuxPlugin.initializeCamera().then((value) {
timer = new Timer.periodic(
Duration(milliseconds: 150),
(Timer t) => widget.cameraLinuxPlugin.captureImage().then((value) {
if (mounted) {
setState(() {
_Image = value;
try {
Provider.of<FlwtchState>(context, listen: false).cwtch.SendMessage(Provider.of<ContactInfoState>(context, listen: false).profileOnion,
Provider.of<ContactInfoState>(context, listen: false).identifier, jsonEncode(VidMessage(o: VideoOverlay, d: _Image)));
} catch (e) {
EnvironmentConfig.debugLog("could not send ${Base85Codec.new().encode(_Image)}: $e");
}
});
}
}));
});
}
@override
Widget build(BuildContext context) {
return Image.memory(
_Image,
width: 320,
height: 240,
gaplessPlayback: true,
errorBuilder: (context, error, stackTrace) {
return Container();
},
);
}
}

View File

@ -9,6 +9,8 @@ list(APPEND FLUTTER_PLUGIN_LIST
)
list(APPEND FLUTTER_FFI_PLUGIN_LIST
camera_linux
miniaudio
)
set(PLUGIN_BUNDLED_LIBRARIES)

View File

@ -113,6 +113,13 @@ packages:
url: "https://pub.dev"
source: hosted
version: "8.6.1"
camera_linux:
dependency: "direct main"
description:
path: "lib/third_party/camera_linux"
relative: true
source: path
version: "0.0.8"
characters:
dependency: transitive
description:
@ -157,10 +164,10 @@ packages:
dependency: transitive
description:
name: collection
sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
url: "https://pub.dev"
source: hosted
version: "1.17.2"
version: "1.18.0"
connectivity_plus:
dependency: "direct main"
description:
@ -471,10 +478,10 @@ packages:
dependency: transitive
description:
name: meta
sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e
url: "https://pub.dev"
source: hosted
version: "1.9.1"
version: "1.10.0"
mime:
dependency: transitive
description:
@ -483,6 +490,13 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.4"
miniaudio:
dependency: "direct main"
description:
path: "lib/third_party/miniaudio"
relative: true
source: path
version: "0.0.1"
msix:
dependency: "direct dev"
description:
@ -591,10 +605,10 @@ packages:
dependency: transitive
description:
name: platform
sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76"
sha256: ae68c7bfcd7383af3629daafb32fb4e8681c7154428da4febcff06200585f102
url: "https://pub.dev"
source: hosted
version: "3.1.0"
version: "3.1.2"
plugin_platform_interface:
dependency: transitive
description:
@ -724,18 +738,18 @@ packages:
dependency: transitive
description:
name: stack_trace
sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
url: "https://pub.dev"
source: hosted
version: "1.11.0"
version: "1.11.1"
stream_channel:
dependency: transitive
description:
name: stream_channel
sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
url: "https://pub.dev"
source: hosted
version: "2.1.1"
version: "2.1.2"
stream_transform:
dependency: transitive
description:
@ -772,10 +786,10 @@ packages:
dependency: transitive
description:
name: test_api
sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8"
sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
url: "https://pub.dev"
source: hosted
version: "0.6.0"
version: "0.6.1"
timezone:
dependency: transitive
description:
@ -884,10 +898,10 @@ packages:
dependency: transitive
description:
name: vm_service
sha256: c620a6f783fa22436da68e42db7ebbf18b8c44b9a46ab911f666ff09ffd9153f
sha256: c538be99af830f478718b51630ec1b6bee5e74e52c8a802d328d9e71d35d2583
url: "https://pub.dev"
source: hosted
version: "11.7.1"
version: "11.10.0"
watcher:
dependency: transitive
description:
@ -900,10 +914,10 @@ packages:
dependency: transitive
description:
name: web
sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10
sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152
url: "https://pub.dev"
source: hosted
version: "0.1.4-beta"
version: "0.3.0"
web_socket_channel:
dependency: transitive
description:
@ -961,7 +975,7 @@ packages:
source: hosted
version: "6.3.0"
yaml:
dependency: transitive
dependency: "direct main"
description:
name: yaml
sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5"
@ -969,5 +983,5 @@ packages:
source: hosted
version: "3.1.2"
sdks:
dart: ">=3.1.0-185.0.dev <4.0.0"
dart: ">=3.2.0-194.0.dev <4.0.0"
flutter: ">=3.7.0"

View File

@ -54,6 +54,10 @@ dependencies:
dbus: ^0.7.8
connectivity_plus:
path: lib/third_party/connectivity_plus/connectivity_plus
camera_linux:
path: lib/third_party/camera_linux
miniaudio:
path: lib/third_party/miniaudio
# misc plugins
qr_flutter: ^4.0.0