I am currently working on a Flutter project and utilizing the circular_countdown_timer package to display a countdown timer. However, I am facing a challenge in implementing a feature where I want to play a "Tic" audio during the last 5 seconds of the countdown. Specifically, I would like to play a "Tic" audio for each last second of the countdown, summing up to a total of 5 "Tic" sounds.
I am seeking guidance on how to achieve this functionality within my Flutter application. How can I trigger the audio playback during the last 5 seconds of the countdown, ensuring that the "Tic" audio is played for each last second that counts down?
Any insights, suggestions, or code samples related to integrating audio playback during the countdown using the circular_countdown_timer package would be highly appreciated.
Thank you in advance for your support and expertise in resolving this challenge.
Widget:
/// Returns Body as per mode or mode conditions
Widget returnSmQuizBodyWidget({required BuildContext context}) {
if (_soloModeLogic.currentMode == 'Exclusive'{
return const SMWinScreen();
} else {
return Column(
children: [
//----------------------- Question Container
Stack(
clipBehavior: Clip.none,
children: [
//----------------------- Question Frame
returnQuestionFrame(context: context),
//----------------------- Timer
Positioned(
right: 0,
left: 0,
bottom: -25,
child: CircularCountDownTimer(
duration: _soloModeLogic.quizTime,
initialDuration: 0,
controller: _soloModeLogic.countDownController,
width: 5.w,
height: 7.h,
ringColor: Colors.grey.shade400,
ringGradient: null,
fillColor: _soloModeLogic.isFreezeColor
? Colors.lightBlueAccent
: Colors.red,
fillGradient: null,
backgroundColor: const Color(0xfff5f5f5),
backgroundGradient: null,
strokeWidth: 4.w,
strokeCap: StrokeCap.butt,
textStyle: TextStyle(
fontSize: 20.sp,
color: _soloModeLogic.isFreezeColor
? Colors.lightBlueAccent
: Colors.red,
fontWeight: FontWeight.bold,
),
textFormat: CountdownTextFormat.S,
isReverse: true,
isReverseAnimation: false,
isTimerTextShown: true,
autoStart: true,
onStart: () {},
onChange: (v) {},
onComplete: () =>
_soloModeLogic.onTimeOut(context: context),
),
),
],
),
],
);
}
}
I have created a demo app.
based on your code.
It does what you need.
One important thing I came to realize is that during the last five seconds, instead of playing/doing pause each second, which causes sync loss between counter and audio player, start playing audio from the last 5th second and stop at or before zero and select suitable audio file that takes appx 1 second to play a sound.
You can change the audio speed to adjust and you can also look out for alternate audio player library.
You can do anything with the code.(Fork/copy-pase,etc)
Thanks :)
Edit :
I realized that in future, I may delete the app from the repo, hence pasting important parts of the code here.
I have assets/tick.mp3 file in the root directory.
This is my pubspec.yaml file.
name: solution_76450197
description: A new Flutter project.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1
environment:
sdk: '>=3.0.3 <4.0.0'
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.2
circular_countdown_timer: ^0.2.3
audioplayers: ^4.1.0
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^2.0.0
flutter:
uses-material-design: true
assets:
- assets/
This is my main.dart file.
import 'package:audioplayers/audioplayers.dart';
import 'package:circular_countdown_timer/circular_countdown_timer.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class SoloModeLogic {
String currentMode = "none";
bool isFreezeColor = false;
final audioPlayer = AudioPlayer()..setSource(AssetSource('tick.mp3'));
int quizTime = 10;
final CountDownController countDownController = CountDownController();
// The length indicates threshold seconds (last five seconds)
List<bool> threshold = [false, false ,false,false,false];
onTimeOut({required BuildContext context}) {
print("time out");
audioPlayer.pause();
//restartCountdown();
}
// Please not that it's not called at every second change but instead
// called on more smaller unit of second second.
// Hence it could be called multiple times per second
void onCountdownChange(String v) {
int vInt = int.parse(v);
if (vInt > 0 && vInt < threshold.length + 1 && !threshold[vInt-1]) {
audioPlayer.pause();
threshold[vInt-1] = true;
audioPlayer.seek(const Duration(milliseconds: 0));
audioPlayer.resume();
} else if (vInt == 0) {
audioPlayer.pause();
}
}
void restartCountdown() {
audioPlayer.pause();
threshold = threshold.map((e) => false).toList();
countDownController.restart(duration: quizTime);
}
}
final _soloModeLogic = SoloModeLogic();
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({super.key});
@override
Widget build(BuildContext context) {
return returnSmQuizBodyWidget(context: context);
}
/// Returns Body as per mode or mode conditions
Widget returnSmQuizBodyWidget({required BuildContext context}) {
if (_soloModeLogic.currentMode == 'Exclusive') {
return const Text("Exclusive Mode");
} else {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
//----------------------- Question Container
Stack(
clipBehavior: Clip.none,
children: [
//----------------------- Question Frame
const Text("My Question"),
//----------------------- Timer
Positioned(
right: 0,
left: 0,
top: (MediaQuery.of(context).size.height / 2),
child: CircularCountDownTimer(
duration: _soloModeLogic.quizTime,
initialDuration: 0,
controller: _soloModeLogic.countDownController,
width: 50,
height: 70,
ringColor: Colors.grey.shade400,
ringGradient: null,
fillColor: _soloModeLogic.isFreezeColor
? Colors.lightBlueAccent
: Colors.red,
fillGradient: null,
backgroundColor: const Color(0xfff5f5f5),
backgroundGradient: null,
strokeWidth: 4,
strokeCap: StrokeCap.butt,
textStyle: TextStyle(
fontSize: 20,
color: _soloModeLogic.isFreezeColor
? Colors.lightBlueAccent
: Colors.red,
fontWeight: FontWeight.bold,
),
textFormat: CountdownTextFormat.S,
isReverse: true,
isReverseAnimation: false,
isTimerTextShown: true,
autoStart: false,
onStart: () {},
onChange: _soloModeLogic.onCountdownChange,
onComplete: () => _soloModeLogic.onTimeOut(context: context),
),
),
],
),
FloatingActionButton(
onPressed: () {
_soloModeLogic.restartCountdown();
},
child: Text("Start"),
),
// This trailing comma makes auto-formatting nicer for build methods.
],
);
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With