I am uploading image using Dio. I got the upload progress in percentage but I also want
to get the upload reaming time.
onSendProgress: (int sent, int total) {
uploadProgress.value = "${(sent / total * 100).toStringAsFixed (0)}%";
},
Is there any way to get the reaming time ?
Convert the remaining file size to megabytes.
Convert upload speed to megabytes.
file size / (uploads per second / 8 )
ex) 200M/(10M/8) = 160 seconds
I simulated an upload environment, I believe you can apply it to the Dio environment, good luck.
void test() {
var totalSize = 120000.0;
var uploadSpeed = 0.0;
var timeLeft = 0.0;
var startTime = DateTime.now();
var curTime = DateTime.now();
Timer? timer;
timer = Timer.periodic(Duration(seconds: 1), (t) {
if (t.tick > 9) timer?.cancel();
curTime = DateTime.now();
var currentSize = 1500。0;
var usedTime =
((curTime.difference(startTime).inMilliseconds) / 1000).toInt();
uploadSpeed = (totalSize / usedTime) / 1024;
totalSize = totalSize - currentSize;
timeLeft = totalSize / (currentSize / 8);
print('useTime : $usedTime');
print('uploadSpeed : $uploadSpeed');
print('File Size : $totalSize');
print('uploadSpeed :$uploadSpeed');
print('timeLeft $timeLeft');
});
}
Related
I want to get percentage of ffmpeg execution in flutter
I have some code example but I don't know to do this
ANDROID EXAMPLE:
int start = message.indexOf("time=");
int end = message.indexOf(" bitrate");
if (start != -1 && end != -1) {
String duration = message.substring(start + 5, end);
if (duration != "") {
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
dialog.setProgress((int)sdf.parse("1970-01-01 " + duration).getTime());
}catch (ParseException e)
{
e.printStackTrace();
}
}
}
FLUTTER CODE :
void statisticsCallback(Statistics statistics) {
print("Statistics: executionId: ${statistics.executionId}, time: ${statistics.time}, size: ${statistics.size}, bitrate: ${statistics.bitrate}, speed: ${statistics.speed}, videoFrameNumber: ${statistics.videoFrameNumber}, videoQuality: ${statistics.videoQuality}, videoFps: ${statistics.videoFps}");
}
how can I generate progress of execution from statisticsCallback method?
Please help me out
There is another approach to solve this issue .
first to get the totalFileDuration using FFprobe instead of initializing VideoPlayer
as follows :
final FlutterFFprobe flutterFFprobe = FlutterFFprobe();
MediaInformation mediaInformation =
await flutterFFprobe.getMediaInformation(audioPath!);
Map? _mediaProperties = mediaInformation.getMediaProperties();
final _videoDuration = double.parse(_mediaProperties!["duration"].toString());
Then as the last answer suggests :
void statisticsCallback(Statistics statistics) {
totalProgress = (statistics.time * 100) ~/ _videoDuration;
print("Statistics: executionId: ${statistics.executionId}, time: ${statistics.time}, size: ${statistics.size}, bitrate: ${statistics.bitrate}, speed: ${statistics.speed}, videoFrameNumber: ${statistics.videoFrameNumber}, videoQuality: ${statistics.videoQuality}, videoFps: ${statistics.videoFps}");
}
Following Documents: https://pub.dev/packages/flutter_ffmpeg
First you have to enable StatisticsCallback, this can be placed inside the initState
#override
void initState() {
super.initState();
final FlutterFFmpegConfig _flutterFFmpegConfig = new FlutterFFmpegConfig();
_flutterFFmpegConfig.enableStatisticsCallback(this.statisticsCallback);
}
Then in your statisticsCallback function, you get statistics.time and totalDurationFile(inMilliseconds) calculate
void statisticsCallback(Statistics statistics) {
totalProgress = (statistics.time * 100) ~/ totalFileDuration;
print("Statistics: executionId: ${statistics.executionId}, time: ${statistics.time}, size: ${statistics.size}, bitrate: ${statistics.bitrate}, speed: ${statistics.speed}, videoFrameNumber: ${statistics.videoFrameNumber}, videoQuality: ${statistics.videoQuality}, videoFps: ${statistics.videoFps}");
}
Update: https://pub.dev/packages/ffmpeg_kit_flutter
FFmpegKit.executeAsync(arguments, (session) async {
final returnCode = await session.getReturnCode();
if (ReturnCode.isSuccess(returnCode)) {
/// When sucess
} else if (ReturnCode.isCancel(returnCode)) {
/// When cancel
}
}, (Log log) {},
(Statistics statistics) {
if (statistics == null) {
return;
}
if (statistics.getTime() > 0) {
totalProgress = (statistics.getTime() * 100) ~/ totalVideoDuration;
}
});
Assuming you have the File Instance of the video
you can get the progress of the ongoing compression like this
/// initialize the videoController to get its meta data
final VideoPlayerController _controller = VideoPlayerController.file(video);
await _controller.initialize();
int videoInSeconds = _controller.value.duration.inSeconds;
/// enable the statistics Callback to get the ongoing compression metadata
_flutterFFmpegConfig.enableStatisticsCallback((x){
double percentage = ((x.time / 1000) / videoInSeconds ) * 100;
debugPrint('progress = ${percentage.toStringAsFixed(0)} %'); // progress = [0 - 100] %
});
I'm learning Dart & flutter for 2 days and I'm confused about how to convert seconds (for example 1500sec) to minutes.
For studying the new language, I'm making Pomodoro timer, and for test purposes, I want to convert seconds to MM: SS format. So far, I got this code below, but I'm stuck for a couple of hours now... I googled it but could not solve this problem, so I used Stackoverflow. How should I fix the code?
int timeLeftInSec = 1500;
void startOrStop() {
timer = Timer.periodic(Duration(seconds: 1), (timer) {
setState(() {
if (timeLeftInSec > 0) {
timeLeftInSec--;
timeLeft = Duration(minutes: ???, seconds: ???)
} else {
timer.cancel();
}
}
}
}
This code works for me
formatedTime({required int timeInSecond}) {
int sec = time % 60;
int min = (time / 60).floor();
String minute = min.toString().length <= 1 ? "0$min" : "$min";
String second = sec.toString().length <= 1 ? "0$sec" : "$sec";
return "$minute : $second";
}
now just call the function
formatedTime(timeInSecond: 152)
formated time example
Without formatting:
int mins = Duration(seconds: 120).inMinutes; // 2 mins
Formatting:
String formatTime(int seconds) {
return '${(Duration(seconds: seconds))}'.split('.')[0].padLeft(8, '0');
}
void main() {
String time = formatTime(3700); // 01:01:11
}
You can try this :
int minutes = (seconds / 60).truncate();
String minutesStr = (minutes % 60).toString().padLeft(2, '0');
This is the way I've achieved desired format of MM:SS
Duration(seconds: _secondsLeft--).toString().substring(2, 7);
Here is an example of what toString method returns:
d = Duration(days: 0, hours: 1, minutes: 10, microseconds: 500);
d.toString(); // "1:10:00.000500"
So with the substring method chained you can easily achive more formats e.g. HH:MM:SS etc.
Check out this piece of code for a count down timer with formatted output
import 'dart:async';
void main(){
late Timer timer;
int startSeconds = 120; //time limit
String timeToShow = "";
timer = Timer.periodic(Duration(seconds:1 ),(time){
startSeconds = startSeconds-1;
if(startSeconds ==0){
timer.cancel();
}
int minutes = (startSeconds/60).toInt();
int seconds = (startSeconds%60);
timeToShow = minutes.toString().padLeft(2,"0")+"."+seconds.toString().padLeft(2,"0");
print(timeToShow);
});
}
/*output
01.59
01.58
01.57
...
...
...
00.02
00.01
00.00*/
static int timePassedFromNow(String? dateTo) {
if (dateTo != null) {
DateTime targetDateTime = DateTime.parse(dateTo);
DateTime dateTimeNow = DateTime.now();
if (targetDateTime.isAfter(dateTimeNow)) {
Duration differenceInMinutes = dateTimeNow.difference(targetDateTime);
return differenceInMinutes.inSeconds;
}
}
return 0;
}
static String timeLeft(int seconds) {
int diff = seconds;
int days = diff ~/ (24 * 60 * 60);
diff -= days * (24 * 60 * 60);
int hours = diff ~/ (60 * 60);
diff -= hours * (60 * 60);
int minutes = diff ~/ (60);
diff -= minutes * (60);
String result = "${twoDigitNumber(days)}:${twoDigitNumber(hours)}:${twoDigitNumber(minutes)}";
return result;
}
static String twoDigitNumber(int? dateTimeNumber) {
if (dateTimeNumber == null) return "0";
return (dateTimeNumber < 9 ? "0$dateTimeNumber" : dateTimeNumber).toString();
}
I know that you can change the formatting of Eclipse in Window>Preferences>Java>Code Style>Formatter
But I don't know where to make it put a newline between variables and loops/if-else.
I need this:
isRunning = true;
final double frameTime = 1.0 / FRAME_CAP;
long lastTime = Time.getTime();
double unproccessedTime = 0;
while(isRunning)
{
long startTime = Time.getTime();
long passedTime = startTime - lastTime;
lastTime = startTime;
unproccessedTime += passedTime / (double)Time.SECOND;
while(unproccessedTime > frameTime)
{
unproccessedTime -= frameTime;
if(Window.isCloseRequested())
{
stop();
}
}
render();
}
To become more like this:
isRunning = true;
final double frameTime = 1.0 / FRAME_CAP;
long lastTime = Time.getTime();
double unproccessedTime = 0;
while(isRunning)
{
long startTime = Time.getTime();
long passedTime = startTime - lastTime;
lastTime = startTime;
unproccessedTime += passedTime / (double)Time.SECOND;
while(unproccessedTime > frameTime)
{
unproccessedTime -= frameTime;
if(Window.isCloseRequested())
{
stop();
}
}
render();
}
Can anyone tell me which format setting could perform this?
I usually like to working with clean code too,and was wondering the same thing before, But I use Regex with Find and Replace:
Find: ^.+if
Replace with: \R$0
Find: ^\s*\n
Replace with: (empty)
This was answer I found before that does works as well
How to add a new line BEFORE a line that matches a given pattern?
I have some error related to IndexOutOfRangeException. The number of errors is over 200 and the error comes up when I play the game.
Error shown like this:
IndexOutOfRangeException: Array index is out of range. GameController.OnGUI () (at Assets/MicroRacers Assets/Scripts/GameController.js:67)
Here is the code of my game controller.
var CheckPoints:Transform[];
var LapsToWin:int = 5;
var PointsPerPlace:Array = new Array(8,4,2,1);
var CountDownToStart:float = 5;
var Items:Transform[];
var ItemCopy:Object;
var SpawnTime:Vector2 = Vector2(5,10);
private var SpawnTimeCount:float = 0;
var MaximumItems:int = 5;
private var ItemCount:int = 0;
private var FinishPlace:int = 0;
private var Players:int = 1;
var RaceEndDelay:float = 5;
//~ function Awake()
//~ {
//~ Application.targetFrameRate = 30;
//~ }
function Start()
{
SpawnTimeCount = Random.Range(SpawnTime.x, SpawnTime.y);
}
function Update ()
{
if ( SpawnTimeCount > 0 )
{
SpawnTimeCount -= Time.deltaTime;
}
else if ( ItemCount < MaximumItems )
{
SpawnTimeCount = Random.Range(SpawnTime.x, SpawnTime.y);
ItemCount++;
ItemCopy = Instantiate(Items[Mathf.Floor(Random.Range(0, Items.length - 1))], CheckPoints[Mathf.Floor(Random.Range(0, CheckPoints.length - 1))].position + Vector3.up * 0.3, Quaternion.identity);
ItemCopy.transform.Translate(Vector3.right * Random.Range(-3,3), Space.Self);
}
if ( Players == 0 )
{
RaceEndDelay -= Time.deltaTime;
if ( RaceEndDelay <= 0 )
{
Application.LoadLevel("end");
}
}
}
//This script displays the HUD, with current weapon, ammo left, Health, Shield, and score
var GUIskin:GUISkin; //The skin gui we'll use
var CountdownTextures:Texture2D[];
private var CountdownTextureIndex:int = 0;
function OnGUI()
{
GUI.skin = GUIskin; //The skin gui we'll use
if ( CountDownToStart > Time.timeSinceLevelLoad )
{
GUI.DrawTexture(Rect( (Screen.width - CountdownTextures[Mathf.Round(Time.timeSinceLevelLoad)].width) * 0.5, (Screen.height - CountdownTextures[Mathf.Round(Time.timeSinceLevelLoad)].height) * 0.5, CountdownTextures[Mathf.Round(Time.timeSinceLevelLoad)].width, CountdownTextures[Mathf.Round(Time.timeSinceLevelLoad)].height), CountdownTextures[Mathf.Round(Time.timeSinceLevelLoad)]); //Draw the HUD texture
}
}
Mathf.Round(Time.timeSinceLevelLoad) is just bigger CountdownTextures array size.
Maybe try adding this:
Debug.Log("Index: "+Mathf.Round(Time.timeSinceLevelLoad)+", Array size: "+ CountdownTextures.Length);
And you should see that index is bigger than size.
You can also add kind of safety check inside if, something like this:
if(Mathf.Round(Time.timeSinceLevelLoad) < CountdownTextures.Length && <your second statement>)
I am using Quartz.NET library and I need to execute a job every two days and repeat it every two hours between 22 PM and 6 AM. I don't know how to achieve this. I tried all of triggers combining them with calendars to exclude other hours, but nothing works as I want. Any idea?
This is the answer.
protected void Application_Start()
{
//....
EveryTwoWeek();
//....
}
private void MainJob()
{
int hourNumber = 2;
var schedFact = new Quartz.Impl.StdSchedulerFactory();
var sched = schedFact.GetScheduler();
sched.Start();
var twoHourlyTriggerFrom22To6 = Quartz.TriggerUtils.MakeHourlyTrigger(hourNumber);
twoHourlyTriggerFrom22To6.StartTimeUtc = System.DateTime.Now.Date.AddHours(22);
twoHourlyTriggerFrom22To6.EndTimeUtc = System.DateTime.Now.Date.AddHours(22 + 8);
var jobDetail = new Quartz.JobDetail("Method", methodType);
sched.ScheduleJob(jobDetail, twoHourlyTriggerFrom22To6);
}
private void EveryTwoDays()
{
int dayNumber = 2;
var schedFact = new Quartz.Impl.StdSchedulerFactory();
var sched = schedFact.GetScheduler();
sched.Start();
var everyTwoDaysTrigger = Quartz.TriggerUtils.MakeImmediateTrigger(int.MaxValue, new System.TimeSpan(0, dayNumber * 24, 0, 0));
everyTwoDaysTrigger.StartTimeUtc = System.DateTime.Now.Date;
var jobDetail = new Quartz.JobDetail("MainJob", mainJobType);
sched.ScheduleJob(jobDetail, everyTwoDaysTrigger);
}
What about 0 0 0,2,4,6,22 1/2 * ? *
Strictly speaking, this isn't every two days, but on the 1st, 3rd, 5th etc of each month.