Compare commits
15 Commits
feature-au
...
v1.0.12.11
Author | SHA1 | Date | |
---|---|---|---|
96455092d1 | |||
93854d5b33 | |||
bbfb3175fe | |||
98c2a4243d | |||
c965c42a32 | |||
0ed4e33934 | |||
e5342c386f | |||
447c968395 | |||
56b754e8d1 | |||
685cc35bb7 | |||
95bd0ddfee | |||
39a2c3f91f | |||
5d6a935f3d | |||
db5132a568 | |||
ea38305793 |
21
README.md
21
README.md
@ -3,16 +3,23 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div align="center">
|
<div align="center">
|
||||||
<h1>PiliPala</h1>
|
<h1>PiliPala</h1>
|
||||||
|
<div align="center">
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|
</div>
|
||||||
<p>使用Flutter开发的BiliBili第三方客户端</p>
|
<p>使用Flutter开发的BiliBili第三方客户端</p>
|
||||||
<br/>
|
|
||||||
<img src="https://github.com/guozhigq/pilipala/blob/main/assets/sreenshot/510shots_so.png" width="32%" alt="home" />
|
<img src="https://github.com/guozhigq/pilipala/blob/main/assets/sreenshot/510shots_so.png" width="32%" alt="home" />
|
||||||
<img src="https://github.com/guozhigq/pilipala/blob/main/assets/sreenshot/174shots_so.png" width="32%" alt="home" />
|
<img src="https://github.com/guozhigq/pilipala/blob/main/assets/sreenshot/174shots_so.png" width="32%" alt="home" />
|
||||||
<img src="https://github.com/guozhigq/pilipala/blob/main/assets/sreenshot/850shots_so.png" width="32%" alt="home" />
|
<img src="https://github.com/guozhigq/pilipala/blob/main/assets/sreenshot/850shots_so.png" width="32%" alt="home" />
|
||||||
<br/>
|
<br/>
|
||||||
<img src="https://github.com/guozhigq/pilipala/blob/main/assets/sreenshot/main_screen.png" width="96%" alt="home" />
|
<img src="https://github.com/guozhigq/pilipala/blob/main/assets/sreenshot/main_screen.png" width="96%" alt="home" />
|
||||||
<br/>
|
<br/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
## 开发环境
|
## 开发环境
|
||||||
|
11
change_log/1.0.12.1114.md
Normal file
11
change_log/1.0.12.1114.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
## 1.0.12
|
||||||
|
|
||||||
|
|
||||||
|
### 修复
|
||||||
|
+ iOS端视频播放时没有声音
|
||||||
|
+ 超过6分钟弹幕不显示
|
||||||
|
+ 视频详情页网络异常
|
||||||
|
|
||||||
|
|
||||||
|
更多更新日志可在Github上查看
|
||||||
|
问题反馈、功能建议请查看「关于」页面。
|
@ -115,30 +115,24 @@ class Request {
|
|||||||
idleTimeout: const Duration(milliseconds: 10000),
|
idleTimeout: const Duration(milliseconds: 10000),
|
||||||
onClientCreate: (_, config) => config.onBadCertificate = (_) => true,
|
onClientCreate: (_, config) => config.onBadCertificate = (_) => true,
|
||||||
),
|
),
|
||||||
)
|
);
|
||||||
|
|
||||||
/// 设置代理
|
/// 设置代理
|
||||||
..httpClientAdapter = IOHttpClientAdapter(
|
if (enableSystemProxy) {
|
||||||
|
dio.httpClientAdapter = IOHttpClientAdapter(
|
||||||
createHttpClient: () {
|
createHttpClient: () {
|
||||||
final client = HttpClient();
|
final client = HttpClient();
|
||||||
// Config the client.
|
// Config the client.
|
||||||
client.findProxy = (uri) {
|
client.findProxy = (uri) {
|
||||||
if (enableSystemProxy) {
|
// return 'PROXY host:port';
|
||||||
print('🌹:$systemProxyHost');
|
return 'PROXY $systemProxyHost:$systemProxyPort';
|
||||||
print('🌹:$systemProxyPort');
|
|
||||||
|
|
||||||
// return 'PROXY host:port';
|
|
||||||
return 'PROXY $systemProxyHost:$systemProxyPort';
|
|
||||||
} else {
|
|
||||||
// 不设置代理
|
|
||||||
return 'DIRECT';
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
client.badCertificateCallback =
|
client.badCertificateCallback =
|
||||||
(X509Certificate cert, String host, int port) => true;
|
(X509Certificate cert, String host, int port) => true;
|
||||||
return client;
|
return client;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
//添加拦截器
|
//添加拦截器
|
||||||
dio.interceptors.add(ApiInterceptor());
|
dio.interceptors.add(ApiInterceptor());
|
||||||
|
@ -231,6 +231,15 @@ class _DynamicsPageState extends State<DynamicsPage>
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
SliverToBoxAdapter(
|
||||||
|
child: Container(
|
||||||
|
height: 6,
|
||||||
|
color: Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.onInverseSurface
|
||||||
|
.withOpacity(0.5),
|
||||||
|
),
|
||||||
|
),
|
||||||
FutureBuilder(
|
FutureBuilder(
|
||||||
future: _futureBuilderFuture,
|
future: _futureBuilderFuture,
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
|
@ -56,67 +56,73 @@ class _UpPanelState extends State<UpPanel> {
|
|||||||
floating: true,
|
floating: true,
|
||||||
pinned: false,
|
pinned: false,
|
||||||
delegate: _SliverHeaderDelegate(
|
delegate: _SliverHeaderDelegate(
|
||||||
height: 90,
|
height: 124,
|
||||||
child: Container(
|
child: Column(
|
||||||
height: 90,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
color: Theme.of(context).colorScheme.background,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
child: Row(
|
children: [
|
||||||
children: [
|
Container(
|
||||||
Expanded(
|
color: Theme.of(context).colorScheme.background,
|
||||||
child: ListView(
|
padding: const EdgeInsets.only(left: 16, right: 16),
|
||||||
scrollDirection: Axis.horizontal,
|
child: Row(
|
||||||
controller: scrollController,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
const SizedBox(width: 10),
|
children: [
|
||||||
if (liveList.isNotEmpty) ...[
|
const Text('最新关注'),
|
||||||
for (int i = 0; i < liveList.length; i++) ...[
|
GestureDetector(
|
||||||
upItemBuild(liveList[i], i)
|
onTap: () {
|
||||||
],
|
feedBack();
|
||||||
VerticalDivider(
|
Get.toNamed('/follow?mid=${userInfo.mid}');
|
||||||
indent: 20,
|
},
|
||||||
endIndent: 40,
|
child: Container(
|
||||||
width: 26,
|
padding: const EdgeInsets.only(top: 5, bottom: 5),
|
||||||
color: Theme.of(context)
|
|
||||||
.colorScheme
|
|
||||||
.primary
|
|
||||||
.withOpacity(0.5),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
for (int i = 0; i < upList.length; i++) ...[
|
|
||||||
upItemBuild(upList[i], i)
|
|
||||||
],
|
|
||||||
const SizedBox(width: 10),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Material(
|
|
||||||
child: InkWell(
|
|
||||||
onTap: () => {
|
|
||||||
feedBack(),
|
|
||||||
Get.toNamed('/follow?mid=${userInfo.mid}')
|
|
||||||
},
|
|
||||||
child: Container(
|
|
||||||
height: 100,
|
|
||||||
padding: const EdgeInsets.only(left: 10, right: 10),
|
|
||||||
color: Theme.of(context)
|
|
||||||
.colorScheme
|
|
||||||
.secondaryContainer
|
|
||||||
.withOpacity(0.3),
|
|
||||||
child: Center(
|
|
||||||
child: Text(
|
child: Text(
|
||||||
'全部',
|
'查看全部',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Theme.of(context)
|
color: Theme.of(context).colorScheme.outline),
|
||||||
.colorScheme
|
|
||||||
.onSecondaryContainer),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
)),
|
Container(
|
||||||
),
|
height: 90,
|
||||||
|
color: Theme.of(context).colorScheme.background,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: ListView(
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
controller: scrollController,
|
||||||
|
children: [
|
||||||
|
const SizedBox(width: 10),
|
||||||
|
if (liveList.isNotEmpty) ...[
|
||||||
|
for (int i = 0; i < liveList.length; i++) ...[
|
||||||
|
upItemBuild(liveList[i], i)
|
||||||
|
],
|
||||||
|
VerticalDivider(
|
||||||
|
indent: 20,
|
||||||
|
endIndent: 40,
|
||||||
|
width: 26,
|
||||||
|
color: Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.primary
|
||||||
|
.withOpacity(0.5),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
for (int i = 0; i < upList.length; i++) ...[
|
||||||
|
upItemBuild(upList[i], i)
|
||||||
|
],
|
||||||
|
const SizedBox(width: 10),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,7 +218,10 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void didChangeAppLifecycleState(AppLifecycleState lifecycleState) {
|
void didChangeAppLifecycleState(AppLifecycleState lifecycleState) {
|
||||||
if (lifecycleState == AppLifecycleState.inactive && autoPiP) {
|
var routePath = Get.currentRoute;
|
||||||
|
if (lifecycleState == AppLifecycleState.inactive &&
|
||||||
|
autoPiP &&
|
||||||
|
routePath.startsWith('/video')) {
|
||||||
floating.enable(
|
floating.enable(
|
||||||
aspectRatio: Rational(
|
aspectRatio: Rational(
|
||||||
videoDetailController.data.dash!.video!.first.width!,
|
videoDetailController.data.dash!.video!.first.width!,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// ignore_for_file: avoid_print
|
// ignore_for_file: avoid_print
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:io';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:easy_debounce/easy_throttle.dart';
|
import 'package:easy_debounce/easy_throttle.dart';
|
||||||
@ -337,7 +338,7 @@ class PlPlayerController {
|
|||||||
if (!_listenersInitialized) {
|
if (!_listenersInitialized) {
|
||||||
startListeners();
|
startListeners();
|
||||||
}
|
}
|
||||||
await _initializePlayer(seekTo: seekTo);
|
await _initializePlayer(seekTo: seekTo, duration: _duration.value);
|
||||||
bool autoEnterFullcreen =
|
bool autoEnterFullcreen =
|
||||||
setting.get(SettingBoxKey.enableAutoEnter, defaultValue: false);
|
setting.get(SettingBoxKey.enableAutoEnter, defaultValue: false);
|
||||||
if (autoEnterFullcreen && _isFirstTime) {
|
if (autoEnterFullcreen && _isFirstTime) {
|
||||||
@ -380,8 +381,10 @@ class PlPlayerController {
|
|||||||
// 解除倍速限制
|
// 解除倍速限制
|
||||||
await pp.setProperty("af", "scaletempo2=max-speed=8");
|
await pp.setProperty("af", "scaletempo2=max-speed=8");
|
||||||
// 音量不一致
|
// 音量不一致
|
||||||
await pp.setProperty("volume-max", "100");
|
if (Platform.isAndroid) {
|
||||||
await pp.setProperty("ao", "audiotrack,opensles");
|
await pp.setProperty("volume-max", "100");
|
||||||
|
await pp.setProperty("ao", "audiotrack,opensles");
|
||||||
|
}
|
||||||
|
|
||||||
// 音轨
|
// 音轨
|
||||||
if (dataSource.audioSource != '' && dataSource.audioSource != null) {
|
if (dataSource.audioSource != '' && dataSource.audioSource != null) {
|
||||||
@ -441,12 +444,17 @@ class PlPlayerController {
|
|||||||
// 开始播放
|
// 开始播放
|
||||||
Future _initializePlayer({
|
Future _initializePlayer({
|
||||||
Duration seekTo = Duration.zero,
|
Duration seekTo = Duration.zero,
|
||||||
|
Duration? duration,
|
||||||
}) async {
|
}) async {
|
||||||
// 设置倍速
|
// 设置倍速
|
||||||
if (_playbackSpeed.value != 1.0) {
|
if (videoType.value == 'live') {
|
||||||
await setPlaybackSpeed(_playbackSpeed.value);
|
|
||||||
} else {
|
|
||||||
await setPlaybackSpeed(1.0);
|
await setPlaybackSpeed(1.0);
|
||||||
|
} else {
|
||||||
|
if (_playbackSpeed.value != 1.0) {
|
||||||
|
await setPlaybackSpeed(_playbackSpeed.value);
|
||||||
|
} else {
|
||||||
|
await setPlaybackSpeed(1.0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
getVideoFit();
|
getVideoFit();
|
||||||
// if (_looping) {
|
// if (_looping) {
|
||||||
@ -460,7 +468,7 @@ class PlPlayerController {
|
|||||||
|
|
||||||
// 自动播放
|
// 自动播放
|
||||||
if (_autoPlay) {
|
if (_autoPlay) {
|
||||||
await play();
|
await play(duration: duration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -589,6 +597,7 @@ class PlPlayerController {
|
|||||||
|
|
||||||
/// 设置倍速
|
/// 设置倍速
|
||||||
Future<void> setPlaybackSpeed(double speed) async {
|
Future<void> setPlaybackSpeed(double speed) async {
|
||||||
|
/// TODO _duration.value丢失
|
||||||
await _videoPlayerController?.setRate(speed);
|
await _videoPlayerController?.setRate(speed);
|
||||||
try {
|
try {
|
||||||
DanmakuOption currentOption = danmakuController!.option;
|
DanmakuOption currentOption = danmakuController!.option;
|
||||||
@ -624,7 +633,9 @@ class PlPlayerController {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
/// 播放视频
|
/// 播放视频
|
||||||
Future<void> play({bool repeat = false, bool hideControls = true}) async {
|
/// TODO _duration.value丢失
|
||||||
|
Future<void> play(
|
||||||
|
{bool repeat = false, bool hideControls = true, dynamic duration}) async {
|
||||||
// 播放时自动隐藏控制条
|
// 播放时自动隐藏控制条
|
||||||
controls = !hideControls;
|
controls = !hideControls;
|
||||||
// repeat为true,将从头播放
|
// repeat为true,将从头播放
|
||||||
@ -638,6 +649,9 @@ class PlPlayerController {
|
|||||||
|
|
||||||
playerStatus.status.value = PlayerStatus.playing;
|
playerStatus.status.value = PlayerStatus.playing;
|
||||||
// screenManager.setOverlays(false);
|
// screenManager.setOverlays(false);
|
||||||
|
|
||||||
|
/// 临时fix _duration.value丢失
|
||||||
|
_duration.value = duration;
|
||||||
audioSessionHandler.setActive(true);
|
audioSessionHandler.setActive(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user