Toggle navigation
Toggle navigation
This project
Loading...
Sign in
OnePoem
/
OnePoem-App
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Snippets
Network
Create a new issue
Builds
Commits
Issue Boards
Authored by
Reason Pun
2022-01-25 13:31:36 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
21a53e1e4468283e3b8c9aa4fce7741d921b5e98
21a53e1e
1 parent
f3d915a2
视频录制页面增加了计时器
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
107 additions
and
67 deletions
lib/poem/page/poem_record_video.dart
pubspec.lock
pubspec.yaml
lib/poem/page/poem_record_video.dart
View file @
21a53e1
import
'dart:async'
;
import
'dart:io'
;
import
'package:camera/camera.dart'
;
...
...
@@ -6,6 +7,7 @@ import 'package:flutter/services.dart';
import
'package:one_poem/util/toast_utils.dart'
;
import
'package:one_poem/widgets/my_app_bar.dart'
;
import
'package:path_provider/path_provider.dart'
;
import
'package:pausable_timer/pausable_timer.dart'
;
import
'package:video_player/video_player.dart'
;
import
'package:one_poem/extension/int_extension.dart'
;
...
...
@@ -21,8 +23,7 @@ class _PoemRecordVideoPageState extends State<PoemRecordVideoPage>
CameraController
?
controller
;
VideoPlayerController
?
videoController
;
File
?
_imageFile
;
File
?
_videoFile
;
File
?
_videoFile
;
// 保存的视频文件位置,用于上传视频的时候用!
final
bool
_isVideoCameraSelected
=
true
;
bool
_isCameraInitialized
=
false
;
...
...
@@ -36,6 +37,15 @@ class _PoemRecordVideoPageState extends State<PoemRecordVideoPage>
ResolutionPreset
currentResolutionPreset
=
ResolutionPreset
.
high
;
List
<
CameraDescription
>?
cameras
=
[];
///声明变量
late
final
PausableTimer
_timer
;
///记录当前的时间
int
currentTimer
=
0
;
int
duration
=
60
*
1000
;
@override
void
initState
()
{
// Hide the status bar in Android
...
...
@@ -49,6 +59,20 @@ class _PoemRecordVideoPageState extends State<PoemRecordVideoPage>
Toast
.
show
(
"摄像头出错啦~"
);
}
});
_timer
=
PausableTimer
(
const
Duration
(
milliseconds:
100
),
()
{
currentTimer
+=
100
;
_timer
..
reset
()
..
start
();
if
(
currentTimer
>=
duration
)
{
stopRecordVideo
();
}
setState
(()
{});
},
);
super
.
initState
();
}
...
...
@@ -76,22 +100,6 @@ class _PoemRecordVideoPageState extends State<PoemRecordVideoPage>
fileNames
.
add
({
0
:
int
.
parse
(
name
),
1
:
file
.
path
.
split
(
'/'
).
last
});
}
}
if
(
fileNames
.
isNotEmpty
)
{
final
recentFile
=
fileNames
.
reduce
((
curr
,
next
)
=>
curr
[
0
]
>
next
[
0
]
?
curr
:
next
);
String
recentFileName
=
recentFile
[
1
];
if
(
recentFileName
.
contains
(
'.mp4'
))
{
_videoFile
=
File
(
'
${directory.path}
/
$recentFileName
'
);
_imageFile
=
null
;
_startVideoPlayer
();
}
else
{
_imageFile
=
File
(
'
${directory.path}
/
$recentFileName
'
);
_videoFile
=
null
;
}
setState
(()
{});
}
}
Future
<
XFile
?>
takePicture
()
async
{
...
...
@@ -110,19 +118,6 @@ class _PoemRecordVideoPageState extends State<PoemRecordVideoPage>
}
}
Future
<
void
>
_startVideoPlayer
()
async
{
if
(
_videoFile
!=
null
)
{
videoController
=
VideoPlayerController
.
file
(
_videoFile
!);
await
videoController
!.
initialize
().
then
((
_
)
{
// Ensure the first frame is shown after the video is initialized,
// even before the play button has been pressed.
setState
(()
{});
});
await
videoController
!.
setLooping
(
true
);
await
videoController
!.
play
();
}
}
Future
<
void
>
startVideoRecording
()
async
{
final
CameraController
?
cameraController
=
controller
;
...
...
@@ -239,9 +234,34 @@ class _PoemRecordVideoPageState extends State<PoemRecordVideoPage>
void
dispose
()
{
controller
?.
dispose
();
videoController
?.
dispose
();
///取消计时器
_timer
.
cancel
();
super
.
dispose
();
}
Future
<
void
>
stopRecordVideo
()
async
{
try
{
XFile
?
rawVideo
=
await
stopVideoRecording
();
File
videoFile
=
File
(
rawVideo
!.
path
);
int
currentUnix
=
DateTime
.
now
().
millisecondsSinceEpoch
;
final
directory
=
await
getApplicationDocumentsDirectory
();
String
fileFormat
=
videoFile
.
path
.
split
(
'.'
).
last
;
_videoFile
=
await
videoFile
.
copy
(
'
${directory.path}
/
$currentUnix
.
$fileFormat
'
,
);
// TODO why pause!直接使用cancel()会出现问题,暂时这么解决
_timer
.
pause
();
}
catch
(
e
)
{
// print(e);
}
}
@override
Widget
build
(
BuildContext
context
)
{
return
SafeArea
(
...
...
@@ -266,11 +286,11 @@ class _PoemRecordVideoPageState extends State<PoemRecordVideoPage>
),
),
Padding
(
padding:
const
EdgeInsets
.
fromLTRB
(
16.
0
,
8.
0
,
16.
0
,
8.
0
,
padding:
EdgeInsets
.
fromLTRB
(
16
.
px
,
8
.
px
,
16
.
px
,
8
.
px
,
),
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
end
,
...
...
@@ -281,14 +301,17 @@ class _PoemRecordVideoPageState extends State<PoemRecordVideoPage>
),
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
crossAxisAlignment:
CrossAxisAlignment
.
end
,
children:
[
InkWell
(
onTap:
_isRecordingInProgress
?
()
async
{
if
(
controller
!.
value
.
isRecordingPaused
)
{
await
resumeVideoRecording
();
_timer
.
start
();
}
else
{
await
pauseVideoRecording
();
_timer
.
pause
();
}
}
:
()
{
...
...
@@ -305,29 +328,29 @@ class _PoemRecordVideoPageState extends State<PoemRecordVideoPage>
child:
Stack
(
alignment:
Alignment
.
center
,
children:
[
const
Icon
(
Icon
(
Icons
.
circle
,
color:
Colors
.
black38
,
size:
60
,
size:
60
.
px
,
),
_isRecordingInProgress
?
controller
!.
value
.
isRecordingPaused
?
const
Icon
(
?
Icon
(
Icons
.
play_arrow
,
color:
Colors
.
white
,
size:
30
,
size:
30
.
px
,
)
:
const
Icon
(
:
Icon
(
Icons
.
pause
,
color:
Colors
.
white
,
size:
30
,
size:
30
.
px
,
)
:
Icon
(
_isRearCameraSelected
?
Icons
.
camera_front
:
Icons
.
camera_rear
,
color:
Colors
.
white
,
size:
30
,
size:
30
.
px
,
),
],
),
...
...
@@ -335,24 +358,12 @@ class _PoemRecordVideoPageState extends State<PoemRecordVideoPage>
InkWell
(
onTap:
()
async
{
if
(
_isRecordingInProgress
)
{
XFile
?
rawVideo
=
await
stopVideoRecording
();
File
videoFile
=
File
(
rawVideo
!.
path
);
int
currentUnix
=
DateTime
.
now
().
millisecondsSinceEpoch
;
final
directory
=
await
getApplicationDocumentsDirectory
();
String
fileFormat
=
videoFile
.
path
.
split
(
'.'
).
last
;
_videoFile
=
await
videoFile
.
copy
(
'
${directory.path}
/
$currentUnix
.
$fileFormat
'
,
);
_startVideoPlayer
();
stopRecordVideo
();
}
else
{
currentTimer
=
0
;
_timer
..
reset
()
..
start
();
await
startVideoRecording
();
}
},
...
...
@@ -364,21 +375,40 @@ class _PoemRecordVideoPageState extends State<PoemRecordVideoPage>
color:
_isVideoCameraSelected
?
Colors
.
white
:
Colors
.
white38
,
size:
80
,
size:
80
.
px
,
),
_isRecordingInProgress
?
SizedBox
(
width:
60
.
px
,
height:
60
.
px
,
child:
CircularProgressIndicator
(
strokeWidth:
5
.
px
,
value:
currentTimer
/
duration
,
),
)
:
Container
(),
Icon
(
Icons
.
circle
,
color:
_isVideoCameraSelected
?
Colors
.
red
:
Colors
.
white
,
size:
65
,
size:
65
.
px
,
),
_isRecordingInProgress
?
Container
()
:
Text
(
"60s"
,
style:
TextStyle
(
fontSize:
12
.
px
,
color:
Colors
.
white
,
),
),
_isVideoCameraSelected
&&
_isRecordingInProgress
?
const
Icon
(
?
Icon
(
Icons
.
stop_rounded
,
color:
Colors
.
white
,
size:
32
,
size:
32
.
px
,
)
:
Container
(),
],
...
...
@@ -388,16 +418,16 @@ class _PoemRecordVideoPageState extends State<PoemRecordVideoPage>
onTap:
()
{},
child:
Stack
(
alignment:
Alignment
.
center
,
children:
const
[
children:
[
Icon
(
Icons
.
circle
,
color:
Colors
.
black38
,
size:
60
,
size:
60
.
px
,
),
Icon
(
Icons
.
photo_album
,
color:
Colors
.
white
,
size:
30
,
size:
30
.
px
,
),
],
),
...
...
pubspec.lock
View file @
21a53e1
...
...
@@ -701,6 +701,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.5"
pausable_timer:
dependency: "direct main"
description:
name: pausable_timer
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0+3"
pedantic:
dependency: transitive
description:
...
...
pubspec.yaml
View file @
21a53e1
...
...
@@ -99,6 +99,9 @@ dependencies:
camera
:
^0.9.4+5
path_provider
:
^2.0.8
# A Dart timer that can be paused, resumed and reset.
pausable_timer
:
^1.0.0+3
dependency_overrides
:
decimal
:
1.5.0
...
...
Please
register
or
login
to post a comment