video: handle audio focus
This commit is contained in:
parent
1ab0760adc
commit
856050f7b3
2 changed files with 44 additions and 4 deletions
|
@ -1,18 +1,21 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:typed_data';
|
|
||||||
|
|
||||||
import 'package:aves/model/entry.dart';
|
import 'package:aves/model/entry.dart';
|
||||||
import 'package:aves/model/settings/enums/video_loop_mode.dart';
|
import 'package:aves/model/settings/enums/video_loop_mode.dart';
|
||||||
import 'package:aves/model/settings/settings.dart';
|
import 'package:aves/model/settings/settings.dart';
|
||||||
import 'package:aves/model/video/keys.dart';
|
import 'package:aves/model/video/keys.dart';
|
||||||
import 'package:aves/model/video/metadata.dart';
|
import 'package:aves/model/video/metadata.dart';
|
||||||
|
import 'package:aves/services/common/optional_event_channel.dart';
|
||||||
import 'package:aves/utils/change_notifier.dart';
|
import 'package:aves/utils/change_notifier.dart';
|
||||||
import 'package:aves/widgets/viewer/video/controller.dart';
|
import 'package:aves/widgets/viewer/video/controller.dart';
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:fijkplayer/fijkplayer.dart';
|
import 'package:fijkplayer/fijkplayer.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
class IjkPlayerAvesVideoController extends AvesVideoController {
|
class IjkPlayerAvesVideoController extends AvesVideoController {
|
||||||
|
final EventChannel _eventChannel = const OptionalEventChannel('befovy.com/fijk/event');
|
||||||
|
|
||||||
late FijkPlayer _instance;
|
late FijkPlayer _instance;
|
||||||
final List<StreamSubscription> _subscriptions = [];
|
final List<StreamSubscription> _subscriptions = [];
|
||||||
final StreamController<FijkValue> _valueStreamController = StreamController.broadcast();
|
final StreamController<FijkValue> _valueStreamController = StreamController.broadcast();
|
||||||
|
@ -94,6 +97,7 @@ class IjkPlayerAvesVideoController extends AvesVideoController {
|
||||||
|
|
||||||
void _startListening() {
|
void _startListening() {
|
||||||
_instance.addListener(_onValueChanged);
|
_instance.addListener(_onValueChanged);
|
||||||
|
_subscriptions.add(_eventChannel.receiveBroadcastStream().listen((event) => _onPluginEvent(event as Map?)));
|
||||||
_subscriptions.add(_valueStream.where((value) => value.state == FijkState.completed).listen((_) => _completedNotifier.notify()));
|
_subscriptions.add(_valueStream.where((value) => value.state == FijkState.completed).listen((_) => _completedNotifier.notify()));
|
||||||
_subscriptions.add(_instance.onTimedText.listen(_timedTextStreamController.add));
|
_subscriptions.add(_instance.onTimedText.listen(_timedTextStreamController.add));
|
||||||
_subscriptions.add(settings.updateStream
|
_subscriptions.add(settings.updateStream
|
||||||
|
@ -135,7 +139,13 @@ class IjkPlayerAvesVideoController extends AvesVideoController {
|
||||||
|
|
||||||
void _applyOptions(int startMillis) {
|
void _applyOptions(int startMillis) {
|
||||||
// FFmpeg options
|
// FFmpeg options
|
||||||
// cf https://github.com/Bilibili/ijkplayer/blob/master/ijkmedia/ijkplayer/ff_ffplay_options.h
|
// `setHostOption`, cf:
|
||||||
|
// - https://fijkplayer.befovy.com/docs/zh/host-option.html
|
||||||
|
// - https://github.com/deckerst/fijkplayer/blob/master/android/src/main/java/com/befovy/fijkplayer/HostOption.java
|
||||||
|
// `setFormatOption`, cf https://github.com/FFmpeg/FFmpeg/blob/master/libavcodec/options_table.h
|
||||||
|
// `setCodecOption`, cf https://github.com/FFmpeg/FFmpeg/blob/master/libavformat/options_table.h
|
||||||
|
// `setSwsOption`, cf https://github.com/FFmpeg/FFmpeg/blob/master/libswscale/options.c
|
||||||
|
// `setPlayerOption`, cf https://github.com/Bilibili/ijkplayer/blob/master/ijkmedia/ijkplayer/ff_ffplay_options.h
|
||||||
// cf https://www.jianshu.com/p/843c86a9e9ad
|
// cf https://www.jianshu.com/p/843c86a9e9ad
|
||||||
// cf https://www.jianshu.com/p/3649c073b346
|
// cf https://www.jianshu.com/p/3649c073b346
|
||||||
|
|
||||||
|
@ -166,10 +176,15 @@ class IjkPlayerAvesVideoController extends AvesVideoController {
|
||||||
|
|
||||||
// `enable-snapshot`: enable snapshot interface
|
// `enable-snapshot`: enable snapshot interface
|
||||||
// default: 0, in [0, 1]
|
// default: 0, in [0, 1]
|
||||||
// cf https://fijkplayer.befovy.com/docs/zh/host-option.html
|
|
||||||
// there is a performance cost, and it should be set up before playing
|
// there is a performance cost, and it should be set up before playing
|
||||||
options.setHostOption('enable-snapshot', captureFrameEnabled ? 1 : 0);
|
options.setHostOption('enable-snapshot', captureFrameEnabled ? 1 : 0);
|
||||||
|
|
||||||
|
// default: 0, in [0, 1]
|
||||||
|
options.setHostOption('request-audio-focus', 1);
|
||||||
|
|
||||||
|
// default: 0, in [0, 1]
|
||||||
|
options.setHostOption('release-audio-focus', 1);
|
||||||
|
|
||||||
// `accurate-seek-timeout`: accurate seek timeout
|
// `accurate-seek-timeout`: accurate seek timeout
|
||||||
// default: 5000 ms, in [0, 5000]
|
// default: 5000 ms, in [0, 5000]
|
||||||
options.setPlayerOption('accurate-seek-timeout', 1000);
|
options.setPlayerOption('accurate-seek-timeout', 1000);
|
||||||
|
@ -286,6 +301,31 @@ class IjkPlayerAvesVideoController extends AvesVideoController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// cf https://developer.android.com/reference/android/media/AudioManager
|
||||||
|
static const int _audioFocusLoss = -1;
|
||||||
|
static const int _audioFocusRequestFailed = 0;
|
||||||
|
|
||||||
|
void _onPluginEvent(Map? fields) {
|
||||||
|
if (fields == null) return;
|
||||||
|
final event = fields['event'] as String?;
|
||||||
|
switch (event) {
|
||||||
|
case 'volume':
|
||||||
|
// ignore
|
||||||
|
break;
|
||||||
|
case 'audiofocus':
|
||||||
|
final value = fields['value'] as int?;
|
||||||
|
if (value != null) {
|
||||||
|
switch (value) {
|
||||||
|
case _audioFocusLoss:
|
||||||
|
case _audioFocusRequestFailed:
|
||||||
|
pause();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void _onValueChanged() {
|
void _onValueChanged() {
|
||||||
if (_instance.state == FijkState.prepared && _streams.isEmpty) {
|
if (_instance.state == FijkState.prepared && _streams.isEmpty) {
|
||||||
_fetchStreams();
|
_fetchStreams();
|
||||||
|
|
|
@ -267,7 +267,7 @@ packages:
|
||||||
description:
|
description:
|
||||||
path: "."
|
path: "."
|
||||||
ref: aves
|
ref: aves
|
||||||
resolved-ref: "556b3348a616c835d564b023f8ef6f056f67ef16"
|
resolved-ref: "69193da9a6b7f8b5cec5627253982adc303dbf46"
|
||||||
url: "https://github.com/deckerst/fijkplayer.git"
|
url: "https://github.com/deckerst/fijkplayer.git"
|
||||||
source: git
|
source: git
|
||||||
version: "0.10.0"
|
version: "0.10.0"
|
||||||
|
|
Loading…
Reference in a new issue