I am trying to play an audio by using package audioplayer but I cannot always know if a path is a local file or not. Therefore, I wonder what is the best way to determine if a path is local in Flutter?
Both File and Directory classes of dart:io library has isAbsolute method, which checks if a File or Directory path is absolute or not.
final file = File('foo/bar');
print(file.isAbsolute);
/// check if a path is local path in OS filesystem JUST in syntax not really
// final bool isAbsolutePath = !_imagePath!.contains('http://');
// final bool isAbsolutePath = File(_imagePath!).isAbsolute; // import 'dart:io';
final bool isAbsolutePath = p.isAbsolute(_imagePath!); // import 'package:path/path.dart' as p;
Related
I have an mp3 audio file located under this link:
https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3
How can I get its duration in my flutter app without getting the whole audio ?
Just it's length duration? I want the quickest possible way to get it.
You could go with the just_audio package.
import 'package:just_audio/just_audio.dart';
final player = AudioPlayer(); // Create a player
final duration = await player.setUrl( // Load a URL
'https://example.com/bar.mp3'); // Schemes: (https: | file: | asset: )
What is the best option to:
Record audio from microphone,
Store the audio as files in memory,
Being able to play those files ?
Is there one package that is convenient to record and play? Does it works on all platforms (web compatible)? What is the best strategy to store them in memory?
Here is a package you can use audio_recorder
For record and storing part here is sample examples (read the package documentation)
// Import package
import 'package:audio_recorder/audio_recorder.dart';
// Check permissions before starting
bool hasPermissions = await AudioRecorder.hasPermissions;
// Get the state of the recorder
bool isRecording = await AudioRecorder.isRecording;
// Start recording
await AudioRecorder.start(path: _controller.text, audioOutputFormat: AudioOutputFormat.AAC);
// Stop recording
Recording recording = await AudioRecorder.stop();
print("Path : ${recording.path}, Format : ${recording.audioOutputFormat}, Duration : ${recording.duration}, Extension : ${recording.extension},");
play audio you need another package i suggest audioplayers :
// To pause
int result = await audioPlayer.pause();
//To Stop
int result = await audioPlayer.stop();
// To Jump through
int result = await audioPlayer.seek(Duration(milliseconds: 1200));
// To Resume
int result = await audioPlayer.resume();
On my iOS device, I'm accessing the camera through a CameraController (provided by the camera package) with controller.startImageStream((CameraImage img) {...}
The data coming out of the camera is in a bgra8888 format on my phone, but I've read that it's in yuv420 on android devices. To convert the image stream data to a usable, consistent format, I'm using:
import 'dart:typed_data';
import 'package:camera/camera.dart';
import 'package:image/image.dart' as im;
Uint8List concatenatePlanes(List<Plane> planes) {
final WriteBuffer allBytes = WriteBuffer();
planes.forEach((Plane plane) => allBytes.putUint8List(plane.bytes));
return allBytes.done().buffer.asUint8List();
}
List<CameraDescription> cameras = await availableCameras();
CameraController controller = CameraController(cameras[0], ResolutionPreset.medium);
controller.startImageStream((CameraImage img) {
print(img.format.group); // returns ImageFormatGroup.bgra8888
List<int> imgData = concatenatePlanes(img.planes);
im.Image image = im.decodeImage(imgData);
});
The imgData variable is full of data streaming off the camera, but the converted image returned from decodeImage is null.
I had read on other posts that the image package would be up to the task of decoding bgra8888/yuv420 images (https://stackoverflow.com/a/57635827/479947) but I'm not seeing support in its formats.dart source (https://github.com/brendan-duncan/image/blob/master/lib/src/formats/formats.dart).
The target Image format is defined as:
An image buffer where pixels are encoded into 32-bit unsigned ints
(Uint32). Pixels are stored in 32-bit unsigned integers in #AARRGGBB
format. This is to be consistent with the Flutter image data.
How would I get my image stream image in bgra8888/yuv420 converted into the desired Image format?
Have you check this? convertImage
If you convert from bgra8888 to Image, it's kinda fast but yuv420 to Image take much more time, so if you have problem about performance, I can help a little bit with my experience. By the way, if you have performance problem and trying using Isolate, u will meet the memory issue.
Currently I am using the following piece of code to load Textures from image files.
Texture my_pic = (Texture) AssetDatabase.LoadAssetAtPath(path, typeof(Texture));
Unfortunately this method doesn't work if the target path isn't in the Asset/ folder. I was wondering how I would load an image, given some absolute path of the form
/Users/Alan/SomeFolder/SomePic.png
(note that I am currently writing a custom Unity editor plugin by extending EditorWindow if that matters)
AssetDatabase is an Editor-only class.
Furthermore, it can only read assets in the /Assets directory (you know, the ones that are known to the asset database).
If you want to read any file on the file system, you need to use the System.IO classes.
Here is some code that will open a unity file dialog, and load the selected texture into a material of the attached object.
string path = EditorUtility.OpenFilePanel("Load an image", "", "png");
if (string.IsNullOrEmpty(path)) {
return;
}
// Load the images bytes from file (this is a synchronous call!)
byte[] bytes = null;
try {
bytes = System.IO.File.ReadAllBytes(path);
} catch (System.Exception e) {
Debug.LogError(e.Message);
return;
}
// Load the bytes into a Unity Texture2D
Texture2D _tex = new Texture2D(2,2);
_tex.LoadImage(bytes);
// Apply this texture to the object
Renderer r = (target as Component).gameObject.GetComponent<Renderer>();
if (r != null) {
r.material.SetTexture("_MainTex", _tex);
}
The last part, just for demonstration, will work only on a script derived from Editor because it uses target to find the attached renderer. It's up to you to decide what to do with the texture in your EditorWindow script.
Also, remember to explicitly call DestroyImmediate on your texture when you no longer need it, as you may end up with a memory leak in your editor code.
You can use UnityWebRequestTexture
var www = UnityWebRequestTexture.GetTexture("file:///Users/Alan/SomeFolder/SomePic.png");
www.SendWebRequest();
while(!www.isDone)
continue;
var texture = DownloadHandlerTexture.GetContent(www);
Background
I am developing a Unity editor plugin that enables users to send a selected image file to a REST API endpoint in the cloud for processing (e.g. adding transforms and optimizations). The plugin also shows a comparison of the selected image's details before and after processing (e.g. width/height/size before vs after).
The user selects the desired image through the following piece of code:
selected_texture = (Texture2D) EditorGUI.ObjectField(drawing_rect, selected_texture, typeof(Texture2D), false);
Once its selected, I can then get the respective file size by doing this:
file_size = new FileInfo(AssetDatabase.GetAssetPath(selected_texture)).Length;
Problem
This works for most textures selected, but I encounter an error when I choose a built-in Unity texture. Any guidance would be greatly appreciated.
FileNotFoundException: Could not find file 'Resources/unity_builtin_extra'
There are two built-in asset-librarys in Unity:
BuiltIn-Library in "Resources/unity_builtin_extra": contains UGUI sprite、Default-Material、Shader and so on.
BuiltIn-Library in "Library/unity default resources": contains built-in 3D mesh and OnGUI assets.
If you are using AssetDatabase.GetAssetPath, you will always get one or another path above.
To solve the problem, you need do something like below code:
public const string BuiltinResources = "Resources/unity_builtin_extra";
public const string BuiltinExtraResources = "Library/unity default resources";
public static bool IsBuiltInAsset(string assetPath)
{
return assetPath.Equals(BuiltinResources) || assetPath.Equals(BuiltinExtraResources);
}
public static long GetTextureFileLength(Texture texture)
{
string texturePath = AssetDatabase.GetAssetPath(texture);
if (IsBuiltInAsset(texturePath))
{
/*
* You can get all built-in assets by this way.
*
var allAssets = AssetDatabase.LoadAllAssetsAtPath(BuiltinResources);
var allExtraAssets = AssetDatabase.LoadAllAssetsAtPath(BuiltinExtraResources);
*/
// not supportted
// return -1;
// using MemorySize
return Profiler.GetRuntimeMemorySizeLong(texture);
}
else
{
return new FileInfo(texturePath).Length;
}
}