웹 브라우저: 다른 화면으로 가면 페이지의 동영상 · 소리 멈춤
브라우저에서 [다운로드] → 목록 보기 (또는 플레이어 · 설정 등) 로 가면 가려진 브라우저에서 YouTube 가 계속 재생되어 소리만 났다. 브라우저 위에 다른 화면이 올라오면 (RouteAware.didPushNext) 페이지의 video · audio 를 멈춘다 (WebNav.pauseMedia, Edge · Chrome · Android 웹뷰 공통). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>main
parent
39f65f414c
commit
07ec8cd4a5
|
|
@ -507,6 +507,7 @@ class JjCapCutApp extends StatelessWidget {
|
||||||
theme: buildTheme(),
|
theme: buildTheme(),
|
||||||
navigatorKey: navigatorKey,
|
navigatorKey: navigatorKey,
|
||||||
scaffoldMessengerKey: messengerKey,
|
scaffoldMessengerKey: messengerKey,
|
||||||
|
navigatorObservers: [browserRouteObserver],
|
||||||
// 모든 화면에: 환경 설정 · 종료 버튼이 쓸 것 + 끌어다 놓은 동영상을 목록에 추가
|
// 모든 화면에: 환경 설정 · 종료 버튼이 쓸 것 + 끌어다 놓은 동영상을 목록에 추가
|
||||||
builder: (context, child) => AppScope(
|
builder: (context, child) => AppScope(
|
||||||
controller: controller,
|
controller: controller,
|
||||||
|
|
|
||||||
|
|
@ -30,8 +30,17 @@ abstract class WebNav {
|
||||||
|
|
||||||
/// YouTube · Google 로그인 쿠키를 yt-dlp 용 cookies.txt 로 내보내기
|
/// YouTube · Google 로그인 쿠키를 yt-dlp 용 cookies.txt 로 내보내기
|
||||||
Future<void> exportCookies();
|
Future<void> exportCookies();
|
||||||
|
|
||||||
|
/// 페이지의 동영상 · 소리 멈추기 (다른 화면으로 갈 때)
|
||||||
|
Future<void> pauseMedia();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 페이지의 모든 동영상 · 소리를 멈추는 스크립트
|
||||||
|
const pauseMediaScript = "document.querySelectorAll('video,audio').forEach(function(m){try{m.pause()}catch(e){}})";
|
||||||
|
|
||||||
|
/// 화면 이동 알림 (브라우저 위에 다른 화면이 올라오면 동영상을 멈춘다). MaterialApp.navigatorObservers 에 넣는다.
|
||||||
|
final browserRouteObserver = RouteObserver<ModalRoute<void>>();
|
||||||
|
|
||||||
/// 웹뷰 → 화면으로 알리는 통로
|
/// 웹뷰 → 화면으로 알리는 통로
|
||||||
class BrowserHost {
|
class BrowserHost {
|
||||||
final void Function(String url) onUrl;
|
final void Function(String url) onUrl;
|
||||||
|
|
@ -97,7 +106,7 @@ class BrowserPage extends StatefulWidget {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _BrowserPageState extends State<BrowserPage> {
|
class _BrowserPageState extends State<BrowserPage> with RouteAware {
|
||||||
late String _url = widget.initialUrl ?? widget.c.settings.homeUrl;
|
late String _url = widget.initialUrl ?? widget.c.settings.homeUrl;
|
||||||
String _title = '';
|
String _title = '';
|
||||||
double _progress = 1;
|
double _progress = 1;
|
||||||
|
|
@ -138,8 +147,22 @@ class _BrowserPageState extends State<BrowserPage> {
|
||||||
BrowserPage._open++;
|
BrowserPage._open++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didChangeDependencies() {
|
||||||
|
super.didChangeDependencies();
|
||||||
|
final route = ModalRoute.of(context);
|
||||||
|
if (route != null) browserRouteObserver.subscribe(this, route);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 다운로드 목록 · 플레이어 · 설정 등이 위에 올라왔다: 보던 동영상을 멈춘다 (가려진 채 소리만 나지 않게)
|
||||||
|
@override
|
||||||
|
void didPushNext() {
|
||||||
|
_nav?.pauseMedia();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
browserRouteObserver.unsubscribe(this);
|
||||||
BrowserPage._open--;
|
BrowserPage._open--;
|
||||||
_address.dispose();
|
_address.dispose();
|
||||||
_addressFocus.dispose();
|
_addressFocus.dispose();
|
||||||
|
|
@ -492,6 +515,13 @@ class _InAppNav implements WebNav {
|
||||||
final String dataDir;
|
final String dataDir;
|
||||||
_InAppNav(this.c, this.env, this.dataDir);
|
_InAppNav(this.c, this.env, this.dataDir);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> pauseMedia() async {
|
||||||
|
try {
|
||||||
|
await c.evaluateJavascript(source: pauseMediaScript);
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
|
||||||
static const _cookieSites = [
|
static const _cookieSites = [
|
||||||
'https://www.youtube.com/',
|
'https://www.youtube.com/',
|
||||||
'https://m.youtube.com/',
|
'https://m.youtube.com/',
|
||||||
|
|
@ -642,6 +672,13 @@ class _CefNav implements WebNav {
|
||||||
final String dataDir;
|
final String dataDir;
|
||||||
_CefNav(this.c, this.dataDir);
|
_CefNav(this.c, this.dataDir);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> pauseMedia() async {
|
||||||
|
try {
|
||||||
|
await c.evaluateJavascript(pauseMediaScript);
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
|
||||||
/// YouTube · Google 쿠키를 yt-dlp 용 cookies.txt 로 (Edge 와 같은 파일 - 지금 쓰는 엔진의 로그인이 쓰인다).
|
/// YouTube · Google 쿠키를 yt-dlp 용 cookies.txt 로 (Edge 와 같은 파일 - 지금 쓰는 엔진의 로그인이 쓰인다).
|
||||||
/// Chrome 엔진은 쿠키의 이름 · 값만 알려 주므로 만료 · 보안 표시는 기본값으로 적는다.
|
/// Chrome 엔진은 쿠키의 이름 · 값만 알려 주므로 만료 · 보안 표시는 기본값으로 적는다.
|
||||||
@override
|
@override
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,9 @@ class _Backend implements DownloadBackend {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _Nav implements WebNav {
|
class _Nav implements WebNav {
|
||||||
|
int paused = 0;
|
||||||
|
@override
|
||||||
|
Future<void> pauseMedia() async => paused++;
|
||||||
final loads = <String>[];
|
final loads = <String>[];
|
||||||
@override
|
@override
|
||||||
Future<void> load(String url) async => loads.add(url);
|
Future<void> load(String url) async => loads.add(url);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue