102 lines
2.8 KiB
Dart
102 lines
2.8 KiB
Dart
import 'dart:io';
|
|
import 'dart:typed_data';
|
|
import 'package:kusoft/kusoft.dart' as kb;
|
|
import '../core/transport/ikar_network.dart';
|
|
|
|
/// Media reservations are short-lived URLs on ikar_server.
|
|
class IkarMediaSession {
|
|
IkarMediaSession(this.baseUri);
|
|
final Uri baseUri;
|
|
String userAgent() => 'IKAR/1.0.0 Android';
|
|
final _client = IkarNetwork.client();
|
|
Stream<kb.UploadEvent> _upload(
|
|
String url,
|
|
Stream<List<int>> bytes,
|
|
int size,
|
|
String filename,
|
|
String contentType,
|
|
) async* {
|
|
try {
|
|
final uri = Uri.parse(url);
|
|
if (uri.host != baseUri.host ||
|
|
uri.scheme != baseUri.scheme ||
|
|
uri.port != baseUri.port)
|
|
throw StateError('Адрес загрузки принадлежит другому серверу');
|
|
final request = await _client.postUrl(
|
|
uri.replace(
|
|
queryParameters: {...uri.queryParameters, 'filename': filename},
|
|
),
|
|
);
|
|
request.headers.set('Content-Type', contentType);
|
|
request.contentLength = size;
|
|
var sent = 0;
|
|
await for (final chunk in bytes) {
|
|
request.add(chunk);
|
|
sent += chunk.length;
|
|
yield kb.UploadEvent_Progress(
|
|
sent: BigInt.from(sent),
|
|
total: BigInt.from(size),
|
|
);
|
|
}
|
|
final response = await request.close().timeout(
|
|
const Duration(minutes: 5),
|
|
);
|
|
final body = await response.fold<List<int>>(
|
|
[],
|
|
(buffer, chunk) => buffer..addAll(chunk),
|
|
);
|
|
yield kb.UploadEvent_Done(
|
|
status: response.statusCode,
|
|
body: Uint8List.fromList(body),
|
|
);
|
|
} catch (error) {
|
|
yield kb.UploadEvent_Error(message: '$error');
|
|
}
|
|
}
|
|
|
|
Stream<kb.UploadEvent> uploadFilePath({
|
|
required String url,
|
|
required String path,
|
|
required String filename,
|
|
String? contentType,
|
|
String? connection,
|
|
}) async* {
|
|
final file = File(path);
|
|
yield* _upload(
|
|
url,
|
|
file.openRead(),
|
|
await file.length(),
|
|
filename,
|
|
contentType ?? 'application/octet-stream',
|
|
);
|
|
}
|
|
|
|
Stream<kb.UploadEvent> uploadPhoto({
|
|
required String url,
|
|
required Uint8List data,
|
|
required String filename,
|
|
}) => _upload(url, Stream.value(data), data.length, filename, 'image/jpeg');
|
|
Stream<kb.UploadEvent> uploadPhotoPath({
|
|
required String url,
|
|
required String path,
|
|
required String filename,
|
|
}) => uploadFilePath(
|
|
url: url,
|
|
path: path,
|
|
filename: filename,
|
|
contentType: 'image/jpeg',
|
|
);
|
|
Stream<kb.UploadEvent> uploadVideoPath({
|
|
required String url,
|
|
required String path,
|
|
required int chunkSize,
|
|
required int concurrency,
|
|
}) => uploadFilePath(
|
|
url: url,
|
|
path: path,
|
|
filename: 'video.mp4',
|
|
contentType: 'video/mp4',
|
|
);
|
|
void dispose() => _client.close(force: true);
|
|
}
|