Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ endfunction()
set(LIBMPV "libmpv_aarch64.zip")

# Download URL & SHA256 hash of the libmpv archive.
set(LIBMPV_URL "https://github.com/ErBWs/libmpv-ohos-build/releases/download/20260702/${LIBMPV}")
set(LIBMPV_SHA "e528917a9d2ba7c7d47182ddafa15c1dc025387ae0916ed2ad8e0a108017d48d")
set(LIBMPV_URL "https://github.com/ErBWs/libmpv-ohos-build/releases/download/20260811/${LIBMPV}")
set(LIBMPV_SHA "2bfb9844a7552c450694581b315b26cdf6202eaa57724e9f70f3facfad75163b")

# Download location of the libmpv archive.
set(LIBMPV_ARCHIVE "${CMAKE_CURRENT_SOURCE_DIR}/${LIBMPV}")
Expand Down
3 changes: 2 additions & 1 deletion media_kit/lib/src/player/native/core/native_library.dart
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ abstract class NativeLibrary {
'libmpv.so',
],
'ohos': [
'libmpv.so',
'libmpv.so.2',
],
}[Platform.operatingSystem];
Expand Down Expand Up @@ -92,7 +93,7 @@ abstract class NativeLibrary {
'android':
'Cannot find libmpv.so. Please ensure it\'s presence in the APK.',
'ohos':
'Cannot find libmpv.so.2. Please ensure it\'s presence in the HAP.',
'Cannot find libmpv. Please ensure it\'s presence in the HAP.',
}[Platform.operatingSystem]!,
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,6 @@ class OhosVideoController extends PlatformVideoController {
}
}

/// Listener for updating the --wid property.
Future<void> widListener() {
return lock.synchronized(() async {
final widValue = wid.value?.toString() ?? '0';
await setProperties({'wid': widValue});
// Instead of seeking to the start (Duration.zero), seek to the current playback position
// without jumping the user to the start of the media.
final currentPosition = player.state.position;
await player.seek(currentPosition);
});
}

/// [StreamSubscription] for listening to video [Rect].
StreamSubscription<VideoParams>? videoParamsSubscription;

Expand All @@ -64,7 +52,6 @@ class OhosVideoController extends PlatformVideoController {
super.player,
super.configuration,
) {
wid.addListener(widListener);
videoParamsSubscription = player.stream.videoParams.listen(
(event) => lock.synchronized(() async {
final int width;
Expand Down Expand Up @@ -157,26 +144,48 @@ class OhosVideoController extends PlatformVideoController {
// Store the [VideoController] in the [_controllers].
_controllers[handle] = controller;

await _channel.invokeMethod(
final Map<dynamic, dynamic>? data = await _channel.invokeMethod(
'VideoOutputManager.Create',
{
'handle': handle.toString(),
},
);

await controller.setProperties(
{
'vo': configuration.vo!,
'hwdec': configuration.hwdec!,
'vid': 'auto',
'force-window': 'yes',
'sub-use-margins': 'no',
'sub-scale-with-window': 'no',
'osd-font': 'HarmonyOS Sans SC',
},
if (data == null) {
throw StateError('[OhosVideoController] failed to create video output.');
}

final id = (data['id'] as num).toInt();
final wid = (data['wid'] as num).toInt();
final rect = Rect.fromLTWH(
(data['rect']['left'] as num).toDouble(),
(data['rect']['top'] as num).toDouble(),
(data['rect']['width'] as num).toDouble(),
(data['rect']['height'] as num).toDouble(),
);

await controller.setProperties({'ohos-surface-size': '1x1'});
controller.id.value = id;
controller.rect.value = rect;
controller.wid.value = wid;

await controller.lock.synchronized(() async {
// MPV's HarmonyOS video output requires a valid surface ID before the
// GPU video output is initialized.
await controller.setProperty('vo', 'null');
await controller.setProperties(
{
'ohos-surface-size': '${rect.width.toInt()}x${rect.height.toInt()}',
'wid': wid.toString(),
'hwdec': configuration.hwdec!,
'vid': 'auto',
'force-window': 'yes',
'sub-use-margins': 'no',
'sub-scale-with-window': 'no',
'osd-font': 'HarmonyOS Sans SC',
},
);
await controller.setProperty('vo', configuration.vo!);
});

// Return the [PlatformVideoController].
return controller;
Expand All @@ -200,9 +209,6 @@ class OhosVideoController extends PlatformVideoController {

/// Disposes the instance. Releases allocated resources back to the system.
Future<void> _dispose() async {
super.dispose();
wid.dispose();
wid.removeListener(widListener);
await videoParamsSubscription?.cancel();
final handle = await player.handle;
_controllers.remove(handle);
Expand All @@ -212,46 +218,13 @@ class OhosVideoController extends PlatformVideoController {
'handle': handle.toString(),
},
);
wid.dispose();
super.dispose();
}

/// Currently created [OhosVideoController]s.
static final _controllers = HashMap<int, OhosVideoController>();

/// [MethodChannel] for invoking platform specific native implementation.
static final _channel =
const MethodChannel('com.alexmercerind/media_kit_video')
..setMethodCallHandler(
(MethodCall call) async {
try {
debugPrint(call.method.toString());
debugPrint(call.arguments.toString());
switch (call.method) {
case 'VideoOutput.Resize':
{
// Notify about updated texture ID & [Rect].
final int handle = call.arguments['handle'];
final Rect rect = Rect.fromLTWH(
call.arguments['rect']['left'] * 1.0,
call.arguments['rect']['top'] * 1.0,
call.arguments['rect']['width'] * 1.0,
call.arguments['rect']['height'] * 1.0,
);
final int id = call.arguments['id'];
final int wid = call.arguments['wid'];
_controllers[handle]?.rect.value = rect;
_controllers[handle]?.id.value = id;
_controllers[handle]?.wid.value = wid;
break;
}
default:
{
break;
}
}
} catch (exception, stacktrace) {
debugPrint(exception.toString());
debugPrint(stacktrace.toString());
}
},
);
static const _channel = MethodChannel('com.alexmercerind/media_kit_video');
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ import {
AbilityAware,
AbilityPluginBinding
} from '@ohos/flutter_ohos';
import { TextureUpdateCallback } from './TextureUpdateCallback';
import { Rect, SizeData, Utils } from './Utils';
import { Utils } from './Utils';
import { VideoOutputManager } from './VideoOutputManager';
import { common } from '@kit.AbilityKit';

Expand All @@ -33,7 +32,9 @@ export default class MediaKitVideoPlugin implements FlutterPlugin, MethodCallHan
}

onDetachedFromAbility(): void {
return;
this.videoOutputManager?.disposeAll();
this.videoOutputManager = null;
this.context = null;
}

getUniqueClassName(): string {
Expand All @@ -50,31 +51,21 @@ export default class MediaKitVideoPlugin implements FlutterPlugin, MethodCallHan
if (this.channel != null) {
this.channel.setMethodCallHandler(null);
}
this.videoOutputManager?.disposeAll();
this.videoOutputManager = null;
this.channel = null;
this.binding = null;
}

onMethodCall(call: MethodCall, result: MethodResult): void {
switch (call.method) {
case "VideoOutputManager.Create": {
const handle = parseInt(call.argument("handle"));
const textureUpdateCallback: TextureUpdateCallback = {
onTextureUpdate: (id: number, wid: number, width: number, height: number): void => {
const rect: Rect = {
left: 0,
top: 0,
width: width,
height: height,
}
const args: SizeData = {
handle: handle,
id: id,
wid: wid,
rect: rect,
}
this.channel?.invokeMethod("VideoOutput.Resize", args);
}
if (this.videoOutputManager == null) {
result.error("unavailable", "VideoOutputManager is not attached to an ability.", null);
break;
}
this.videoOutputManager?.create(handle, textureUpdateCallback);
result.success(null);
result.success(this.videoOutputManager.create(handle));
break;
}
case "VideoOutputManager.SetSurfaceSize": {
Expand Down Expand Up @@ -111,4 +102,4 @@ export default class MediaKitVideoPlugin implements FlutterPlugin, MethodCallHan
}
}
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@

import Log from '@ohos/flutter_ohos/src/main/ets/util/Log';
import { SurfaceTextureEntry } from '@ohos/flutter_ohos';
import { TextureUpdateCallback } from './TextureUpdateCallback';
import { TextureRegistry } from '@ohos/flutter_ohos';
import { SizeData } from './Utils';

const TAG = "VideoOutput";

Expand All @@ -18,28 +18,36 @@ export class VideoOutput {
private wid: number = 0;
private w: number = 0;
private h: number = 0;
private textureUpdateCallback: TextureUpdateCallback;
private textureRegistry: TextureRegistry;
private surfaceProducer: SurfaceTextureEntry;
private disposed: boolean = false;

constructor(textureRegistry: TextureRegistry, surfaceProducer: SurfaceTextureEntry,
textureUpdateCallback: TextureUpdateCallback) {
constructor(textureRegistry: TextureRegistry, surfaceProducer: SurfaceTextureEntry) {
this.surfaceProducer = surfaceProducer;
this.textureUpdateCallback = textureUpdateCallback;
this.textureRegistry = textureRegistry;
this.setSurfaceSize(0, 0, true);
this.id = this.surfaceProducer.getTextureId();
this.wid = this.surfaceProducer.getSurfaceId();
this.setSurfaceSize(1, 1, true);
}

dispose(): void {
if (this.disposed) {
return;
}

try {
this.surfaceProducer.release();
this.onSurfaceDestroyed();
this.textureRegistry.unregisterTexture(this.id);
this.disposed = true;
this.id = 0;
this.wid = 0;
this.w = 0;
this.h = 0;
} catch (e) {
Log.e(TAG, `dispose: ${e}`);
}
}

async setSurfaceSize(width: number, height: number, force: boolean = false): Promise<void> {
setSurfaceSize(width: number, height: number, force: boolean = false): void {
try {
if (!force && this.w == width && this.h == height) {
return;
Expand All @@ -48,26 +56,22 @@ export class VideoOutput {
this.w = width;
this.h = height;
this.textureRegistry.setTextureBufferSize(this.id, width, height);
this.onSurfaceCreated();
} catch (e) {
Log.e(TAG, `setSurfaceSize error: ${e}`);
}
}

private async onSurfaceCreated(): Promise<void> {
Log.i(TAG, "onSurfaceCreated");
try {
this.id = this.surfaceProducer.getTextureId();
this.wid = this.surfaceProducer.getSurfaceId();
this.textureUpdateCallback.onTextureUpdate(this.id, this.wid, this.w, this.h);
} catch (e) {
Log.e(TAG, `onSurfaceCreated error: ${e}`);
getSizeData(handle: number): SizeData {
return {
handle: handle,
id: this.id,
wid: this.wid,
rect: {
left: 0,
top: 0,
width: this.w,
height: this.h,
},
}
}

private async onSurfaceDestroyed(): Promise<void> {
Log.i(TAG, "onSurfaceDestroyed");
this.textureUpdateCallback.onTextureUpdate(this.id, 0, 0, 0);
this.surfaceProducer.release();
}
}
}
Loading
Loading