Compare commits
15 Commits
v1.0.11.11
...
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 align="center">
|
||||
<h1>PiliPala</h1>
|
||||
<div align="center">
|
||||
|
||||

|
||||

|
||||

|
||||
</div>
|
||||
<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/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" />
|
||||
<br/>
|
||||
<img src="https://github.com/guozhigq/pilipala/blob/main/assets/sreenshot/main_screen.png" width="96%" alt="home" />
|
||||
<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/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" />
|
||||
<br/>
|
||||
<img src="https://github.com/guozhigq/pilipala/blob/main/assets/sreenshot/main_screen.png" width="96%" alt="home" />
|
||||
<br/>
|
||||
</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),
|
||||
onClientCreate: (_, config) => config.onBadCertificate = (_) => true,
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
/// 设置代理
|
||||
..httpClientAdapter = IOHttpClientAdapter(
|
||||
/// 设置代理
|
||||
if (enableSystemProxy) {
|
||||
dio.httpClientAdapter = IOHttpClientAdapter(
|
||||
createHttpClient: () {
|
||||
final client = HttpClient();
|
||||
// Config the client.
|
||||
client.findProxy = (uri) {
|
||||
if (enableSystemProxy) {
|
||||
print('🌹:$systemProxyHost');
|
||||
print('🌹:$systemProxyPort');
|
||||
|
||||
// return 'PROXY host:port';
|
||||
return 'PROXY $systemProxyHost:$systemProxyPort';
|
||||
} else {
|
||||
// 不设置代理
|
||||
return 'DIRECT';
|
||||
}
|
||||
// return 'PROXY host:port';
|
||||
return 'PROXY $systemProxyHost:$systemProxyPort';
|
||||
};
|
||||
client.badCertificateCallback =
|
||||
(X509Certificate cert, String host, int port) => true;
|
||||
return client;
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
//添加拦截器
|
||||
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(
|
||||
future: _futureBuilderFuture,
|
||||
builder: (context, snapshot) {
|
||||
|
@ -56,67 +56,73 @@ class _UpPanelState extends State<UpPanel> {
|
||||
floating: true,
|
||||
pinned: false,
|
||||
delegate: _SliverHeaderDelegate(
|
||||
height: 90,
|
||||
child: 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),
|
||||
],
|
||||
),
|
||||
),
|
||||
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(
|
||||
height: 124,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
color: Theme.of(context).colorScheme.background,
|
||||
padding: const EdgeInsets.only(left: 16, right: 16),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
const Text('最新关注'),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
feedBack();
|
||||
Get.toNamed('/follow?mid=${userInfo.mid}');
|
||||
},
|
||||
child: Container(
|
||||
padding: const EdgeInsets.only(top: 5, bottom: 5),
|
||||
child: Text(
|
||||
'全部',
|
||||
'查看全部',
|
||||
style: TextStyle(
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.onSecondaryContainer),
|
||||
color: Theme.of(context).colorScheme.outline),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
)),
|
||||
),
|
||||
),
|
||||
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
|
||||
void didChangeAppLifecycleState(AppLifecycleState lifecycleState) {
|
||||
if (lifecycleState == AppLifecycleState.inactive && autoPiP) {
|
||||
var routePath = Get.currentRoute;
|
||||
if (lifecycleState == AppLifecycleState.inactive &&
|
||||
autoPiP &&
|
||||
routePath.startsWith('/video')) {
|
||||
floating.enable(
|
||||
aspectRatio: Rational(
|
||||
videoDetailController.data.dash!.video!.first.width!,
|
||||
|
@ -1,6 +1,7 @@
|
||||
// ignore_for_file: avoid_print
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:easy_debounce/easy_throttle.dart';
|
||||
@ -337,7 +338,7 @@ class PlPlayerController {
|
||||
if (!_listenersInitialized) {
|
||||
startListeners();
|
||||
}
|
||||
await _initializePlayer(seekTo: seekTo);
|
||||
await _initializePlayer(seekTo: seekTo, duration: _duration.value);
|
||||
bool autoEnterFullcreen =
|
||||
setting.get(SettingBoxKey.enableAutoEnter, defaultValue: false);
|
||||
if (autoEnterFullcreen && _isFirstTime) {
|
||||
@ -380,8 +381,10 @@ class PlPlayerController {
|
||||
// 解除倍速限制
|
||||
await pp.setProperty("af", "scaletempo2=max-speed=8");
|
||||
// 音量不一致
|
||||
await pp.setProperty("volume-max", "100");
|
||||
await pp.setProperty("ao", "audiotrack,opensles");
|
||||
if (Platform.isAndroid) {
|
||||
await pp.setProperty("volume-max", "100");
|
||||
await pp.setProperty("ao", "audiotrack,opensles");
|
||||
}
|
||||
|
||||
// 音轨
|
||||
if (dataSource.audioSource != '' && dataSource.audioSource != null) {
|
||||
@ -441,12 +444,17 @@ class PlPlayerController {
|
||||
// 开始播放
|
||||
Future _initializePlayer({
|
||||
Duration seekTo = Duration.zero,
|
||||
Duration? duration,
|
||||
}) async {
|
||||
// 设置倍速
|
||||
if (_playbackSpeed.value != 1.0) {
|
||||
await setPlaybackSpeed(_playbackSpeed.value);
|
||||
} else {
|
||||
if (videoType.value == 'live') {
|
||||
await setPlaybackSpeed(1.0);
|
||||
} else {
|
||||
if (_playbackSpeed.value != 1.0) {
|
||||
await setPlaybackSpeed(_playbackSpeed.value);
|
||||
} else {
|
||||
await setPlaybackSpeed(1.0);
|
||||
}
|
||||
}
|
||||
getVideoFit();
|
||||
// if (_looping) {
|
||||
@ -460,7 +468,7 @@ class PlPlayerController {
|
||||
|
||||
// 自动播放
|
||||
if (_autoPlay) {
|
||||
await play();
|
||||
await play(duration: duration);
|
||||
}
|
||||
}
|
||||
|
||||
@ -589,6 +597,7 @@ class PlPlayerController {
|
||||
|
||||
/// 设置倍速
|
||||
Future<void> setPlaybackSpeed(double speed) async {
|
||||
/// TODO _duration.value丢失
|
||||
await _videoPlayerController?.setRate(speed);
|
||||
try {
|
||||
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;
|
||||
// repeat为true,将从头播放
|
||||
@ -638,6 +649,9 @@ class PlPlayerController {
|
||||
|
||||
playerStatus.status.value = PlayerStatus.playing;
|
||||
// screenManager.setOverlays(false);
|
||||
|
||||
/// 临时fix _duration.value丢失
|
||||
_duration.value = duration;
|
||||
audioSessionHandler.setActive(true);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user