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();
}
Related
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');
});
}
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 have faced with the problem that scrollIntoView some times wokrs good, some times no (in most cases not good).So I tried to find an alternative and some kind of it was this article.
But in my program i needed also a horizontal scrolling to element and vertical scrolling showing element in the top of parent window.
So I modifed code from article.
/* This is the main function where which pass two ref parameters of Parent element & Child element */
function scrollIntoView(parent, child) {
const parentBounding = parent.getBoundingClientRect(),
clientBounding = child.getBoundingClientRect();
const parentTop = parentBounding.top,
clientTop = clientBounding.top,
parentLeft = parentBounding.left,
clientLeft = clientBounding.left - 400; /* 400 is a shift so that each difference is not nailed to the upper left edge. You can delete it */
if (parentTop >= clientTop) {
scrollTo(parent, -(parentTop - clientTop), 300, 'vertical');
}
else {
scrollTo(parent, clientTop - parentTop, 300, 'vertical');
}
if (parentLeft >= clientLeft) {
scrollTo(parent, -(parentLeft - clientLeft), 300, 'horizontal');
}
else {
scrollTo(parent, clientLeft - parentLeft, 300, 'horizontal');
}
}
function scrollTo(element, to, duration, type) {
let start = (type == 'vertical') ? element.scrollTop : element.scrollLeft,
currentTime = 0,
increment = 20;
let animateScroll = function() {
currentTime += increment;
let val = easeInOutQuad(currentTime, start, to, duration);
if (type == 'vertical') {
element.scrollTop = val;
}
else {
element.scrollLeft = val;
}
if (currentTime < duration) {
setTimeout(animateScroll, increment);
}
}
animateScroll();
}
/* Function for smooth scroll animation with the time duration */
function easeInOutQuad(time, startPos, endPos, duration) {
time /= duration / 2;
if (time < 1) return (endPos / 2) * time * time + startPos;
time--;
return (-endPos / 2) * (time * (time - 2) - 1) + startPos;
}
This feature is experimental (At the time of my comment)
Both scrollIntoView() its scrollIntoViewOption.
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 a script that regenerates player's health after 5 seconds:
float counter;
void Update (){
counter += Time.deltaTime;
if(counter > 30minutes){
curHealth++;
counter = 0.0f; }
if(curHealth > 5)
curHealth = 5;
}
Which is attach to my player's health script. I want to start regenerating my player health back when timer is at 0. But I don't know how.
This is my player health script:
//Stats
public int curHealth;
public int maxHealth = 3;
public Collider2D col;
public PlayerHealth playerhealthRef;
public TimeManager countDownTimer;
float counter;
public Animator anima; // drag the panel in here again
private UI_ManagerScripts UIM;
DateTime currentDate;
DateTime oldDate;
private GenerateEnemy generateEnemy = null;
void Start ()
{
curHealth = maxHealth;
currentDate = System.DateTime.Now;
if (countDownTimer != null)
{
// countDownTimer.gameObject.SetActive(false);
countDownTimer.Enable(false);
}
if (GameObject.Find("Spawner"))
{
generateEnemy = GameObject.Find("Spawner").GetComponent<GenerateEnemy>();
}
}
void Update ()
{
counter += Time.deltaTime;
if (curHealth > maxHealth) {
curHealth = maxHealth;
}
if ((curHealth <= 0) && (!countDownTimer.gameObject.activeSelf)) {
Die ();
}
if(counter > 5)
{
curHealth++;
counter = 0.0f;
}
if(curHealth > 3)
curHealth = 3;
}
void Awake()
{
UIM = GameObject.Find ("UIManager").GetComponent<UI_ManagerScripts> ();
}
void Die() {
UIM.EnableBoolAnimator(anima);
PlayerPrefs.SetInt("RemainingLives", curHealth);
PlayerPrefs.Save();
if (generateEnemy != null)
{
generateEnemy.DestroyAllBlobs();
}
if (countDownTimer != null)
{
countDownTimer.Enable(true);
}
}
public void Damage(int dmg)
{
curHealth -= dmg;
}
}
And this is my Timer countdown script:
public Text timer;
int minutes = 1;
int seconds = 0;
float miliseconds = 0;
[Range(1, 59)]
public int defaultStartMinutes = 1;
public bool allowTimerRestart = false;
public bool useElapsedTime = true;
private int savedSeconds = -1;
private bool resetTimer = false;
private DateTime centuryBegin = new DateTime(2001, 1, 1);
private float tickPerSecond = 10000000.0f;
public void Enable (bool enable)
{
gameObject.SetActive(enable);
ResetTime(); // force the timer to restart
}
void Awake ()
{
minutes = defaultStartMinutes;
if (PlayerPrefs.HasKey("TimeOnExit"))
{
miliseconds = PlayerPrefs.GetFloat("TimeOnExit");
savedSeconds = (int)miliseconds;
if (useElapsedTime && PlayerPrefs.HasKey("CurrentTime"))
{
int elapsedTicks = (int)(DateTime.Now.Ticks / tickPerSecond);
int ct = PlayerPrefs.GetInt("CurrentTime", elapsedTicks);
PlayerPrefs.DeleteKey("CurrentTime");
elapsedTicks -= ct;
if (elapsedTicks < miliseconds)
{
miliseconds -= elapsedTicks;
}
else
{
miliseconds = 0;
}
}
minutes = (int)miliseconds / 60;
miliseconds -= (minutes * 60);
seconds = (int)miliseconds;
miliseconds -= seconds;
PlayerPrefs.DeleteKey("TimeOnExit");
}
savedSeconds = 0;
}
public void Update()
{
// count down in seconds
miliseconds += Time.deltaTime;
if (resetTimer)
{
ResetTime();
}
if (miliseconds >= 1.0f)
{
miliseconds -= 1.0f;
if ((seconds > 0) || (minutes > 0))
{
seconds--;
if (seconds < 0)
{
seconds = 59;
minutes--;
}
}
else
{
resetTimer = allowTimerRestart;
}
}
if (seconds != savedSeconds)
{
// Show current time
timer.text = string.Format("{0}:{1:D2}", minutes, seconds);
savedSeconds = seconds;
}
}
void ResetTime()
{
minutes = defaultStartMinutes;
seconds = 0;
savedSeconds = 0;
miliseconds = 1.0f - Time.deltaTime;
resetTimer = false;
}
private void OnApplicationQuit()
{
int numSeconds = ((minutes * 60) + seconds);
if (numSeconds > 0)
{
miliseconds += numSeconds;
PlayerPrefs.SetFloat("TimeOnExit", miliseconds);
if (useElapsedTime)
{
int elapsedTicks = (int)(DateTime.Now.Ticks / tickPerSecond);
PlayerPrefs.SetInt("CurrentTime", elapsedTicks);
}
}
}
}
Thank you :)
Second edit
I tried doing this in my update file:
if (countDownTimer = true)
{
if(counter > 5)
{
curHealth++;
counter = 0.0f;
}
if(curHealth > 3)
curHealth = 3;
}
But I got this error: error CS0029: Cannot implicitly convert type bool' toTimeManager'.
I just wasn't sure of how to go about doing this.?
According to your second edit line 1
if (countDownTimer = true)
should be
if(countDownTimer)
as = operator is only to give a value, and for comparison you use ==, or, if the variable is bool, simply if(var) or if(!var)
Most of your code is useless.
You can use WaitForSeconds(just google it) or you can add LeanTween to your project and use
LeanTweed.DeayedCall(5f, ()=>{ /*code that will be runned after 5 sec will pass*/});
I prefer to use LeanTween.