dragermrb / capacitor-plugin-video-editor Goto Github PK
View Code? Open in Web Editor NEWCapacitor plugin to edit videos
Capacitor plugin to edit videos
i want this on my capacitor 5 ionic 7 app but documentations is not clear
Testing on iOS. We have added this to our project:
VideoEditor.addListener('transcodeProgress', (result) => {
this.ngZone.run(() => {
console.log('transcodeProgress', result);
this.transcodeProgress.message = `Processing... ${(result.progress * 100).toFixed(0)}%`;
});
});
However, we are not getting any messages.
Further review of the code indicates that the progress indicator is not actually wired up. The progressHandler
is defined and passed in, but in the actual implementation the progressHandler
is never called.
Hello,
When i try to create a thumbnail or edit a video using this lib with a .m4v files as input i get the error on IOS : Invalid parameters.
mp4 videos works well.
Is there a way to fixe this ?
Thank you
On iOS, the thumbnail
function always results in a square aspect ratio. I noticed on VideoEditor.swift
, line 111, width and height are being set to the same variable. Could this be made in error? In the Android files, it's implemented properly.
In some instances I am getting this error on Android which is specific to the android.media.MediaMetadataRetriever.setDataSource(MediaMetadataRetriever.java:355)
Line in the Android plugin. It seems to be throwing an exception which crashes my Capacitor app. Should these type of errors be caught and passed back up to the JS level so we could handle them in a try catch around the thumbnail
method
E Serious error executing plugin
java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at com.getcapacitor.PluginHandle.invoke(PluginHandle.java:138)
at com.getcapacitor.Bridge.lambda$callPluginMethod$0$com-getcapacitor-Bridge(Bridge.java:763)
at com.getcapacitor.Bridge$$ExternalSyntheticLambda5.run(Unknown Source:8)
at android.os.Handler.handleCallback(Handler.java:942)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.os.HandlerThread.run(HandlerThread.java:67)
Caused by: java.lang.RuntimeException: setDataSource failed: status = 0x80000000
at android.media.MediaMetadataRetriever._setDataSource(Native Method)
at android.media.MediaMetadataRetriever.setDataSource(MediaMetadataRetriever.java:310)
at android.media.MediaMetadataRetriever.setDataSource(MediaMetadataRetriever.java:253)
at android.media.MediaMetadataRetriever.setDataSource(MediaMetadataRetriever.java:355)
at com.whiteguru.capacitor.plugin.videoeditor.VideoEditorLitr.thumbnail(VideoEditorLitr.java:141)
at com.whiteguru.capacitor.plugin.videoeditor.VideoEditorPlugin.thumbnail(VideoEditorPlugin.java:165)
at java.lang.reflect.Method.invoke(Native Method)
at com.getcapacitor.PluginHandle.invoke(PluginHandle.java:138)
at com.getcapacitor.Bridge.lambda$callPluginMethod$0$com-getcapacitor-Bridge(Bridge.java:763)
at com.getcapacitor.Bridge$$ExternalSyntheticLambda5.run(Unknown Source:8)
at android.os.Handler.handleCallback(Handler.java:942)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.os.HandlerThread.run(HandlerThread.java:67)
E FATAL EXCEPTION: CapacitorPlugins
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at com.getcapacitor.Bridge.lambda$callPluginMethod$0$com-getcapacitor-Bridge(Bridge.java:772)
at com.getcapacitor.Bridge$$ExternalSyntheticLambda5.run(Unknown Source:8)
at android.os.Handler.handleCallback(Handler.java:942)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.os.HandlerThread.run(HandlerThread.java:67)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at com.getcapacitor.PluginHandle.invoke(PluginHandle.java:138)
at com.getcapacitor.Bridge.lambda$callPluginMethod$0$com-getcapacitor-Bridge(Bridge.java:763)
at com.getcapacitor.Bridge$$ExternalSyntheticLambda5.run(Unknown Source:8)
at android.os.Handler.handleCallback(Handler.java:942)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.os.HandlerThread.run(HandlerThread.java:67)
Caused by: java.lang.RuntimeException: setDataSource failed: status = 0x80000000
at android.media.MediaMetadataRetriever._setDataSource(Native Method)
at android.media.MediaMetadataRetriever.setDataSource(MediaMetadataRetriever.java:310)
at android.media.MediaMetadataRetriever.setDataSource(MediaMetadataRetriever.java:253)
at android.media.MediaMetadataRetriever.setDataSource(MediaMetadataRetriever.java:355)
at com.whiteguru.capacitor.plugin.videoeditor.VideoEditorLitr.thumbnail(VideoEditorLitr.java:141)
at com.whiteguru.capacitor.plugin.videoeditor.VideoEditorPlugin.thumbnail(VideoEditorPlugin.java:165)
at java.lang.reflect.Method.invoke(Native Method)
at com.getcapacitor.PluginHandle.invoke(PluginHandle.java:138)
at com.getcapacitor.Bridge.lambda$callPluginMethod$0$com-getcapacitor-Bridge(Bridge.java:763)
at com.getcapacitor.Bridge$$ExternalSyntheticLambda5.run(Unknown Source:8)
at android.os.Handler.handleCallback(Handler.java:942)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.os.HandlerThread.run(HandlerThread.java:67)
I have the following use case:
I get the file path using the video picker
I need to optimize the file so that I can upload it faster
I use a capacitor plugin to reduce the size of the video
This plugin returns an error because it cannot find the file path ;(
const result = await FilePicker.pickVideos({
readData: true
});
const video = result?.files[0];
if (!video.path) { return null; }
const configurations = await this.configurationsService.getConfigurations();
VideoEditor.addListener('transcodeProgress', (info) => {
console.log(info.progress);
});
const editResult = await VideoEditor.edit({
path: video.path,
transcode: {
height: configurations.pictureHeight,
width: configurations.pictureWidth,
keepAspectRatio: true
}
});
Related: capawesome-team/capacitor-plugins#11
@dragermrb - More of a general question. Is there a way to "compress" a video using this plugin. Specifically on IOS with the new cameras even something as simple as a 10-15 seconds video can start getting into the 100+MB range when you read it in the JS layer. I was wondering if there was a way to implement something similar to the Capacitor Camera getPhoto quality setting where the video would not be trimmed into terms of length but we could bring the quality down from like 4k to 720p before reading the file into memory
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR!
npm ERR! While resolving: [email protected]
npm ERR! Found: @capacitor/[email protected]
npm ERR! node_modules/@capacitor/core
npm ERR! @capacitor/core@"5.0.3" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer @capacitor/core@"^4.0.0" from @whiteguru/[email protected]
npm ERR! node_modules/@whiteguru/capacitor-plugin-video-editor
npm ERR! @whiteguru/capacitor-plugin-video-editor@"*" from the root project
npm ERR!
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR!
npm ERR!
npm ERR! For a full report see:
npm ERR! /Users/tianze/.npm/_logs/2023-05-25T09_00_49_539Z-eresolve-report.txt
Hi!.
I'm interested in knowing if it's possible to configure the frames per second (FPS) when editing videos.
Thanks
When trying to use the thumbnail function on Capacitor Android to generate a thumbnail preview I'm getting the following error thrown: "User denied access to storage"
Note: I've also tried adding the following permissions:
uses-permission android:name="android.permission.READ_MEDIA_VIDEO"
Android Version: ~ Android 13 (API level 33)
Code:
if (uri && size) {
try {
const { file } = await VideoEditor.thumbnail({
path: normalizeVideoPath(uri),
width: 600,
height: 600,
at: 0,
});
setFileThumbnail(Capacitor.convertFileSrc(file.path));
} catch (error) {
console.log('THUMB ERROR**', error);
appInsights.trackException({
exception: error,
severityLevel: SeverityLevel.Error,
properties: { name: 'thumbnail creation', fileId },
});
}
}
I have what I believe is the correct permissions in AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
<uses-permission android:name="com.android.vending.BILLING"/>
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
<uses-permission android:name="android.permission.RECORD_AUDIO" />
Logcat Info:
callback: 63712670, pluginId: VideoEditor, methodName: thumbnail, methodData: {"path":"\/storage\/emulated\/0\/Android\/data\\/files\/2518e2d2-f53e-409e-ae59-3ea78f733038-PXL_20221102_142143045.mp4","width":600,"height":600,"at":0}
2023-07-25 14:16:19.351 8950-8950 Capacitor D Sending plugin error: {"save":false,"callbackId":"63712670","pluginId":"VideoEditor","methodName":"thumbnail","success":false,"error":{"message":"User denied access to storage"}}
Hey @dragermrb. We are using this plugin to generate thumbnail previews for movie / video files saved on a user's phone. It's working perfectly on iOS but there seems to be an issue on Android around permissions.
The following is our code:
const { value: devicePath } = await Preferences.get({
key: storageKey,
});
if (devicePath) {
const { uri } = await Filesystem.getUri({
path: devicePath,
directory: getDataDirectory(),
});
if (uri) {
try {
const { file } = await VideoEditor.thumbnail({
path: normalizeVideoPath(uri),
width: 600,
height: 600,
at: 0,
});
setFileThumbnail(Capacitor.convertFileSrc(file.path));
} catch (error) {
appInsights.trackException({
exception: error,
severityLevel: SeverityLevel.Error,
properties: { name: 'thumbnail creation', fileId },
});
}
}
And in out appInsights we are observing the following error after the Android app completely crashes.
Error: User denied access to storage
at returnResult (http://localhost/:745:32)
at win.androidBridge.onmessage (http://localhost/:720:21)
Potential Solution:
Additional Note:
Adding <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
to the AndroidManifest.xml seems to help resolve it
Hey @dragermrb just wanted to first say thanks for the plugin. I did notice a bug though for generating thumbnails. When you pass a file://
path into the thumbnail()
method. It returns an error of "invalid parameters". However it does not happen this for the edit()
method. After looking into the source I code it seems to be that for edit you are normalizing the file path using let path = call.getString("path")?.replacingOccurrences(of: "file://", with: "");
. But do not do this on thumbnails. I confirmed that when editing the uri at the javascript layer thumbnails work and am fine with doing this as a work around for now but figured we might want to handle this at the plugin level to give a consistent approach for both methods.
Note the following code works for Javascript:
const { file } = await VideoEditor.thumbnail({
path: decodeURIComponent(uri.replace('file://', '')),
width: 600,
height: 600,
at: 0,
});
Hello. I'm trying to compress videos to low their size and be able to upload them to my server. I have installed and followed the documentation of yours. The thing is that when my code gets to the point of MediaFileResult it just goes out of the function and I just can not get the result.
So basically here is my code.
I am trying to transcode mov video on ios to mp4. there is no mime-type or format parameter on transcode options, Is it available?
Is it something you will add?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.