Resolves #370 Camera stream support

This commit is contained in:
Yegor Vialov 2020-02-20 14:33:03 +00:00
parent 2f4c06e9b5
commit 35d8607484
5 changed files with 113 additions and 26 deletions

View File

@ -3,12 +3,16 @@ part of '../../main.dart';
class CameraEntity extends Entity {
static const SUPPORT_ON_OFF = 1;
static const SUPPORT_STREAM = 2;
CameraEntity(Map rawData, String webHost) : super(rawData, webHost);
bool get supportOnOff => ((supportedFeatures &
CameraEntity.SUPPORT_ON_OFF) ==
CameraEntity.SUPPORT_ON_OFF);
bool get supportStream => ((supportedFeatures &
CameraEntity.SUPPORT_STREAM) ==
CameraEntity.SUPPORT_STREAM);
@override
Widget _buildAdditionalControlsForPage(BuildContext context) {

View File

@ -10,19 +10,73 @@ class CameraStreamView extends StatefulWidget {
class _CameraStreamViewState extends State<CameraStreamView> {
CameraEntity _entity;
String streamUrl = "";
WebViewController webViewController;
VideoPlayerController videoPlayerController;
Timer monitorTimer;
bool started = false;
double aspectRatio = 1.78;
@override
void initState() {
super.initState();
}
CameraEntity _entity;
String streamUrl = "";
WebViewController webViewController;
void loadStreamUrl() {
setState((){
started = true;
});
Logger.d("[Camera Player] Loading stream url");
HomeAssistant().getCameraStream(_entity.entityId)
.then((data) {
Logger.d("[Camera Player] Stream url: ${ConnectionManager().httpWebHost}${data["url"]}");
if (videoPlayerController != null) {
videoPlayerController.dispose().then((_) => createPlayer(data));
} else {
createPlayer(data);
}
})
.catchError((e) => Logger.e("[Camera Player] $e"));
}
launchStream() {
Launcher.launchURLInCustomTab(
context: context,
url: streamUrl
void createPlayer(data) {
videoPlayerController = VideoPlayerController.network("${ConnectionManager().httpWebHost}${data["url"]}");
videoPlayerController.initialize().then((_) {
setState((){
aspectRatio = videoPlayerController.value.aspectRatio;
});
autoPlay();
startMonitor();
}).catchError((e) {
Logger.e("[Camera Player] Error player init. Retrying");
loadStreamUrl();
});
}
void autoPlay() {
if (!videoPlayerController.value.isPlaying) {
videoPlayerController.play();
}
}
void startMonitor() {
monitorTimer = Timer.periodic(Duration(milliseconds: 500), (timer) {
if (videoPlayerController.value.hasError) {
setState(() {
timer.cancel();
started = false;
});
}
});
}
Widget buildLoading() {
return AspectRatio(
aspectRatio: aspectRatio,
child: Center(
child: CircularProgressIndicator()
)
);
}
@ -32,6 +86,19 @@ class _CameraStreamViewState extends State<CameraStreamView> {
.of(context)
.entityWrapper
.entity;
if (_entity.supportStream && !started) {
loadStreamUrl();
return buildLoading();
} else if (_entity.supportStream && started) {
if (videoPlayerController.value.initialized) {
return AspectRatio(
aspectRatio: aspectRatio,
child: VideoPlayer(videoPlayerController),
);
} else {
return buildLoading();
}
} else {
streamUrl = '${ConnectionManager().httpWebHost}/api/camera_proxy_stream/${_entity
.entityId}?token=${_entity.attributes['access_token']}';
return AspectRatio(
@ -52,9 +119,12 @@ class _CameraStreamViewState extends State<CameraStreamView> {
),
);
}
}
@override
void dispose() {
monitorTimer?.cancel();
videoPlayerController?.dispose();
super.dispose();
}
}

View File

@ -119,6 +119,17 @@ class HomeAssistant {
return completer.future;
}
Future getCameraStream(String entityId) {
Completer completer = Completer();
ConnectionManager().sendSocketMessage(type: "camera/stream", additionalData: {"entity_id": entityId}).then((data) {
completer.complete(data);
}).catchError((e) {
completer.completeError(e);
});
return completer.future;
}
Future _getUserInfo() async {
_userName = null;
await ConnectionManager().sendSocketMessage(type: "auth/current_user").then((data) {

View File

@ -31,6 +31,7 @@ import 'package:battery/battery.dart';
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart' as standaloneWebview;
import 'package:webview_flutter/webview_flutter.dart';
import 'package:video_player/video_player.dart';
import 'utils/logger.dart';

View File

@ -31,6 +31,7 @@ dependencies:
workmanager: ^0.2.0
battery: ^0.3.1+7
firebase_crashlytics: ^0.1.2+5
video_player: ^0.10.7
dev_dependencies: