Skip to content

Feature/null safety #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 17 additions & 19 deletions example/index.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ void main(List<String> arguments) async {
print('Looking for ChromeCast devices...');

List<find_chromecast.CastDevice> devices =
await find_chromecast.find_chromecasts();
await find_chromecast.findChromecasts();
if (devices.length == 0) {
print('No devices found!');
return;
Expand All @@ -50,15 +50,15 @@ void main(List<String> arguments) async {
for (int i = 0; i < devices.length; i++) {
int index = i + 1;
find_chromecast.CastDevice device = devices[i];
print("${index}: ${device.name}");
print("$index: ${device.name}");
}

print("Pick a device (1-${devices.length}):");

int choice = null;
int? choice;

while (choice == null || choice < 0 || choice > devices.length) {
choice = int.parse(stdin.readLineSync());
choice = int.tryParse(stdin.readLineSync()!);
if (choice == null) {
print(
"Please pick a number (1-${devices.length}) or press return to search again");
Expand All @@ -70,9 +70,9 @@ void main(List<String> arguments) async {
host = pickedDevice.ip;
port = pickedDevice.port;

print("Connecting to device: ${host}:${port}");
print("Connecting to device: $host:$port");

log.fine("Picked: ${pickedDevice}");
log.fine("Picked: $pickedDevice");
}

startCasting(media, host, port, argResults['append']);
Expand All @@ -83,12 +83,10 @@ void startCasting(
log.fine('Start Casting');

// try to load previous state saved as json in saved_cast_state.json
Map savedState;
Map? savedState;
try {
File savedStateFile = await File("./saved_cast_state.json");
if (null != savedStateFile) {
savedState = jsonDecode(await savedStateFile.readAsString());
}
File savedStateFile = File("./saved_cast_state.json");
savedState = jsonDecode(await savedStateFile.readAsString());
} catch (e) {
// does not exist yet
log.warning('error fetching saved state' + e.toString());
Expand All @@ -115,7 +113,7 @@ void startCasting(
castSender.castSessionController.stream
.listen((CastSession castSession) async {
if (castSession.isConnected) {
File savedStateFile = await File('./saved_cast_state.json');
File savedStateFile = File('./saved_cast_state.json');
Map map = {
'time': DateTime.now().millisecondsSinceEpoch,
}..addAll(castSession.toMap());
Expand All @@ -124,20 +122,20 @@ void startCasting(
}
});

CastMediaStatus prevMediaStatus;
CastMediaStatus? prevMediaStatus;
// Listen for media status updates, such as pausing, playing, seeking, playback etc.
castSender.castMediaStatusController.stream
.listen((CastMediaStatus mediaStatus) {
// show progress for example
if (null != prevMediaStatus &&
mediaStatus.volume != prevMediaStatus.volume) {
mediaStatus.volume != prevMediaStatus?.volume) {
// volume just updated
log.info('Volume just updated to ${mediaStatus.volume}');
}
if (null == prevMediaStatus ||
mediaStatus?.position != prevMediaStatus?.position) {
mediaStatus.position != prevMediaStatus?.position) {
// update the current progress
log.info('Media Position is ${mediaStatus?.position}');
log.info('Media Position is ${mediaStatus.position}');
}
prevMediaStatus = mediaStatus;
});
Expand Down Expand Up @@ -192,7 +190,7 @@ void startCasting(
// stdin.asBroadcastStream().listen(_handleUserInput);
}

void _handleUserInput(CastSender castSender, List<int> data) {
void _handleUserInput(CastSender? castSender, List<int> data) {
if (null == castSender || data.length == 0) return;

int keyCode = data.last;
Expand All @@ -210,9 +208,9 @@ void _handleUserInput(CastSender castSender, List<int> data) {
// left or right = seek 10s back or forth
double seekBy = 67 == keyCode ? 10.0 : -10.0;
if (null != castSender.castSession &&
null != castSender.castSession.castMediaStatus) {
null != castSender.castSession?.castMediaStatus) {
castSender.seek(
max(0.0, castSender.castSession.castMediaStatus.position + seekBy),
max(0.0, castSender.castSession!.castMediaStatus!.position + seekBy),
);
}
}
Expand Down
24 changes: 12 additions & 12 deletions lib/casting/cast_channel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ abstract class CastChannel {
CastChannel(
this._socket, this._sourceId, this._destinationId, this._namespace);

CastChannel.CreateWithSocket(Socket socket,
{String sourceId, String destinationId, String namespace})
CastChannel.createWithSocket(Socket socket,
{String? sourceId, String? destinationId, String? namespace})
: _socket = socket,
_sourceId = sourceId,
_destinationId = destinationId,
_namespace = namespace;
_sourceId = sourceId ?? "",
_destinationId = destinationId ?? "",
_namespace = namespace ?? "";

void sendMessage(Map payload) async {
payload['requestId'] = _requestId;
Expand All @@ -36,17 +36,17 @@ abstract class CastChannel {

Uint8List bytes = castMessage.writeToBuffer();
Uint32List headers =
Uint32List.fromList(writeUInt32BE(List<int>(4), bytes.lengthInBytes));
Uint32List.fromList(writeUInt32BE([0, 0, 0, 0], bytes.lengthInBytes));
Uint32List fullData =
Uint32List.fromList(headers.toList()..addAll(bytes.toList()));

if ('PING' != payload['type']) {
// print('Send: ${castMessage.toDebugString()}');
// print('List: ${fullData.toList().toString()}');
// if ('PING' != payload['type']) {
// // print('Send: ${castMessage.toDebugString()}');
// // print('List: ${fullData.toList().toString()}');

} else {
print('PING');
}
// } else {
// print('PING');
// }

_socket.add(fullData);

Expand Down
37 changes: 18 additions & 19 deletions lib/casting/cast_device.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import 'dart:typed_data';
import 'package:http/http.dart' as http;
import 'package:http/io_client.dart';
import 'package:logging/logging.dart';
import 'package:observable/observable.dart';
// import 'package:observable/observable.dart';

enum CastDeviceType {
Unknown,
Expand All @@ -25,10 +25,10 @@ enum GoogleCastModelType {
CastGroup,
}

class CastDevice extends ChangeNotifier {
class CastDevice {
final Logger log = Logger('CastDevice');

final String name;
final String? name;
final String type;
final String host;
final int port;
Expand All @@ -45,27 +45,27 @@ class CastDevice extends ChangeNotifier {
/// * ca - Unknown (e.g. "1234");
/// * ic - Icon path (e.g. "/setup/icon.png");
/// * ve - Version (e.g. "04").
final Map<String, Uint8List> attr;
final Map<String, Uint8List>? attr;

String _friendlyName;
String _modelName;
String? _friendlyName;
String? _modelName;

CastDevice({
this.name,
this.type,
this.host,
this.port,
required this.type,
required this.host,
required this.port,
this.attr,
}) {
initDeviceInfo();
}

void initDeviceInfo() async {
if (CastDeviceType.ChromeCast == deviceType) {
if (null != attr && null != attr['fn']) {
_friendlyName = utf8.decode(attr['fn']);
if (null != attr['md']) {
_modelName = utf8.decode(attr['md']);
if (null != attr && null != attr?['fn']) {
_friendlyName = utf8.decode(attr!['fn']!);
if (null != attr?['md']) {
_modelName = utf8.decode(attr!['md']!);
}
} else {
// Attributes are not guaranteed to be set, if not set fetch them via the eureka_info url
Expand All @@ -77,8 +77,8 @@ class CastDevice extends ChangeNotifier {
((X509Certificate cert, String host, int port) =>
trustSelfSigned);
IOClient ioClient = new IOClient(httpClient);
http.Response response = await ioClient.get(
'https://${host}:8443/setup/eureka_info?params=name,device_info');
http.Response response = await ioClient.get(Uri.parse(
'https://$host:8443/setup/eureka_info?params=name,device_info'));
Map deviceInfo = jsonDecode(response.body);

if (deviceInfo['name'] != null && deviceInfo['name'] != 'Unknown') {
Expand All @@ -95,7 +95,7 @@ class CastDevice extends ChangeNotifier {
}
}
}
notifyChange();
// notifyChange();
}

CastDeviceType get deviceType {
Expand All @@ -107,22 +107,21 @@ class CastDevice extends ChangeNotifier {
return CastDeviceType.Unknown;
}

String get friendlyName {
String? get friendlyName {
if (null != _friendlyName) {
return _friendlyName;
}
return name;
}

String get modelName => _modelName;
String? get modelName => _modelName;

GoogleCastModelType get googleModelType {
switch (modelName) {
case "Google Home":
return GoogleCastModelType.GoogleHome;
case "Google Home Hub":
return GoogleCastModelType.GoogleHub;
break;
case "Google Home Mini":
return GoogleCastModelType.GoogleMini;
case "Google Home Max":
Expand Down
48 changes: 27 additions & 21 deletions lib/casting/cast_media.dart
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
class CastMedia {

final String contentId;
String title;
String? title;
bool autoPlay = true;
double position;
String contentType;
List<String> images;
String? artist;
String? albumName;
List<String>? images;

CastMedia({
this.contentId,
required this.contentId,
this.title,
this.artist,
this.albumName,
this.autoPlay = true,
this.position = 0.0,
this.contentType = 'video/mp4',
Expand All @@ -20,20 +23,23 @@ class CastMedia {
}
}

Map toChromeCastMap() {
return {
'type': 'LOAD',
'autoPlay': autoPlay,
'currentTime': position,
'activeTracks': [],
'media': {
'contentId': contentId,
'contentType': contentType,
'images': images,
'title': title,
'streamType': 'BUFFERED',
}
};
}

}
Map toChromeCastMap() => {
'type': 'LOAD',
'autoplay': autoPlay,
'currentTime': position,
'activeTracks': [],
'media': {
'contentId': contentId,
'contentType': contentType,
'streamType': 'BUFFERED',
'metadata': {
'type': 0,
'metadataType': 3,
'albumName': albumName ?? "",
'artist': artist ?? "",
'title': title,
'images': images?.map((e) => {'url': e}).toList()
},
}
};
}
26 changes: 15 additions & 11 deletions lib/casting/cast_media_status.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@ import 'dart:convert';
import 'package:logging/logging.dart';

class CastMediaStatus {

final Logger log = new Logger('CastMediaStatus');

dynamic _sessionId;

final String _nativeStatus;
final bool _isPlaying;
final bool _isPaused;
final bool _isMuted ;
final bool _isMuted;
final bool _isIdle;
final bool _isFinished;
final bool _isCancelled;
Expand All @@ -19,21 +18,27 @@ class CastMediaStatus {
final bool _isBuffering;
final double _volume;
final double _position;
final Map _media;
final Map? _media;

CastMediaStatus.fromChromeCastMediaStatus(Map mediaStatus)
: _sessionId = mediaStatus['mediaSessionId'],
_nativeStatus = mediaStatus['playerState'],
_isIdle = 'IDLE' == mediaStatus['playerState'],
_isPlaying = 'PLAYING' == mediaStatus['playerState'],
_isPaused = 'PAUSED' == mediaStatus['playerState'],
_isMuted = null != mediaStatus['volume'] && true == mediaStatus['volume']['muted'],
_isMuted = null != mediaStatus['volume'] &&
true == mediaStatus['volume']['muted'],
_isLoading = 'LOADING' == mediaStatus['playerState'],
_isBuffering = 'BUFFERING' == mediaStatus['playerState'],
_isFinished = 'IDLE' == mediaStatus['playerState'] && 'FINISHED' == mediaStatus['idleReason'],
_isCancelled = 'IDLE' == mediaStatus['playerState'] && 'CANCELLED' == mediaStatus['idleReason'],
_hasError = 'IDLE' == mediaStatus['playerState'] && 'ERROR' == mediaStatus['idleReason'],
_volume = null != mediaStatus['volume'] ? mediaStatus['volume']['level'].toDouble() : null,
_isFinished = 'IDLE' == mediaStatus['playerState'] &&
'FINISHED' == mediaStatus['idleReason'],
_isCancelled = 'IDLE' == mediaStatus['playerState'] &&
'CANCELLED' == mediaStatus['idleReason'],
_hasError = 'IDLE' == mediaStatus['playerState'] &&
'ERROR' == mediaStatus['idleReason'],
_volume = null != mediaStatus['volume']
? mediaStatus['volume']['level'].toDouble()
: null,
_position = mediaStatus['currentTime'].toDouble(),
_media = mediaStatus['media'];

Expand Down Expand Up @@ -63,7 +68,7 @@ class CastMediaStatus {

double get position => _position;

Map get media => _media;
Map? get media => _media;

@override
String toString() {
Expand All @@ -84,5 +89,4 @@ class CastMediaStatus {
'media': _media
});
}

}
}
Loading