From 93075b9d72375788269655c0bdcda547877e5455 Mon Sep 17 00:00:00 2001 From: David Senk Date: Tue, 8 Oct 2024 14:59:05 -0400 Subject: [PATCH] improved error handling --- assets/audio/internet_error.mp3 | Bin 0 -> 32832 bytes lib/Globals.dart | 60 ++++++++++++++++++++------------ lib/ListenHandler.dart | 20 ++++++++--- lib/main.dart | 3 +- pubspec.yaml | 2 ++ 5 files changed, 57 insertions(+), 28 deletions(-) create mode 100644 assets/audio/internet_error.mp3 diff --git a/assets/audio/internet_error.mp3 b/assets/audio/internet_error.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..f8844132d87526a4b40bc44200ef1d07d1c2ef52 GIT binary patch literal 32832 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%0Ddnt0q}Jy=ie*%)h6Q9~bj=(CnyY3JZ=x z>F~5*1W-s`k@3;DC1y+Pl8g93{5#_Kt9n`TTU^<@h-%waUK^ObV!&{l)z^JPD=VGi zy;yD>Ca=YHI%f0GIustSoL_mJ^!sOTKsL#^T6T+CX5!tsD|B@&`Ls7ai#cu;ogN-O z&TC-2@YGa|Wh=0RdusA3)xQV3c-?i|H9{^V{3xkcTUEp=7RZR{Tib$us-u2m+l6Mw z$B7gtkE3c%t9hQsqH@pAU#ltgi1zLd#*;@jSJ`LcJFrk1&xu_T#sOkL0j|GaQsf`? zk3b|wxf`f$%w%Pba26ec3N^;-fjnpUIeyagl%!8$iZ{YzfTrz{iUsd9hNqxS0yRWP)dae3tkS;uLE zx%sZDWPFaxeWLuOVi-*2%WiNpVz(WS^(QvPiYIY?Fp$*PFP<3rEgKCFpz!RA@9%aY zcSlvr)YQ|VZ<56~d7Iu_+lje$Shp^)?=}7%_`}P5{~Uif$#a({1DELyD6kb;@b9`i zd*i^Dbl~M_-qAAw4JWScl&iN4p(ju->o1ECO53eFO$)8dMR$x>Dz8sK2Ia~Oj)dZV zuWQ>Br7mZt9YG%5tCpVDs$goWTx_5nd1I*J3DR!Mk1VwpIgYBfZn62oHXM9Ayo0+L z)@`Y)g6!=+^r_uTK-k9UZs8;zrcWSW$oUe?Kkw*Ls4IGi(f>1PN5%RjLyOAtK!o4C zN2!_e#mgJ$56Z3H@MVgzFPh#2Q_S6B#luZC6apJ(km2W%^Yn9rXY{x0@S+S|hm8&dOS}`_+(wLX7$nXv7kAvU2xCu0@G=Q=K*%4GXhz7&(v* zVa*|pr$= zNFty@6s#VSH8lr9&mJCf)Va5@cK#tQ1mmFqXG8WWaAn@VQH5S<2P)t#aIR#0HeJw= zwjI80^;Xi}%aDbVErwLbLFB2tIKZ?00b;y=2$S6V|5m=ap!byb@sn7w2i!#ebtR;S0q%a-{ zaL;!r#a^bSYT|)QFa`?<>zkBT>-(G?kJyuu>s2()=!HT{6q5u3=zj7I^r6;%_PGN; z>ii5iS}-a#bc@)0QAb!}Bw261t+Ck28-c=*R9cdTv0I-L)t{j?DvPkbI-1T0DE49G zjm`Ornn{t+t!Lyfmcp0p%!I^BeRHPSe4~3uTU|^0{C{2@e5>1;-Um6ib)Zhu7=HsD z<@{BJ0#*(_~ikIV|ChEV{j)0%hCuP2&oEk4}zB!o6@DqpuA zFEg=qs8T?$5$}JcG2?pOYcW; zSno1LEMJCWa=dH_WG6^K?;pNYJuvcB=o<}OQ);)QF z=@N-ALNl0j^X`Ey!RABdaAvb~`mz#qGgkxMf+Siq1A27?g9?VEQI=#?KUI;g_p4cu-b8mxQwh#ENUf7OJ-KjdMyIw~7rXU9ROpJvv@ zfu3=lr^DUvkoa_Hwr`+^d}5R>nR4dnNXWzn5Axkl`*v%3r(9Q}dQI-VGB{@RHFI{| z_h@>3?O0#?fz}-Y;g)Yd#%H3Q)C_-q=i_Ao<4FcfLE5@}!mk5nxqF1NzBQR{cx6^m z|ES)JwzH-j{$Ud#D2-Uo?&KP9E3r)h%Pyhgl^LSdox6B%fUNS306m~L; z@Gm`JyId0Unkp_dHVd$T>Kp>%$Ly>_pJ0&5M8H`a3NnNtr^G#H0A9|6!jBPkl|qZG?BU1 zHkg>rT?aQ&S;k~Ruk>Okr#0vh5F{idW`4&fA$4s%6F|Qomy?3TKZs(MdDa{Syk@C&bPSx)a(o}hok*=2cFwOm?C1=KLTSpLcBE`I@n?Uni>7); z$A^di`IJ`Ho~@znz<-fhMSz2f86o*1wzDla;2y>^2F}V(>+*@PZaHt?;OV}8tXtHx zD8JGjSX7qe5D0k8J+SLzB|X(=5L$`j4eL!&J<4`xJ*Uz6wb)vi zZ)CTWzGS^RiK@{^cM-W`JU2BCKTf^J2xNRdE*9@xXKAM)hXyIBn;WXUXpO7$D4JlA zL-b@LLRT`JR$R5L7p@x0`3i8*{$19WKoIC<JMO`ea=af<~V?OxN+j#)MLckVEO2)TlM+cNZ7F?9(tM7UO| zd#qYg^Eo?n7x-4nOtTXokfftS)dlb}#lqvpBV>5N5e8r4{GO zcT!{wxRsNkP!^&|^wINKezk1IzuZDkht#-t1S2xRyh??zu_5(=;jjV$J78{0Ymxc14v0sI?GNezmfxW|?!*3F@kFk&BZ>8RA1Zu{2XOlZdt z#y_?dvXaq1*Q3ae5y$ToCIhitbY~AER+~}`Ig2Sre zVEX3hGx5}`a(K9O90Wk(-8l4YYb=$g)Lyf>Nb(1M4UET?et;sAVSTLAa_sAuuXaiV zSrfZn@=5_uFG!nO3>vbzhTe`XvStpl>yJ=m-J%MkteeU869@ALB-hPwt>7zvvzUy9 zGa3p+hC>P~F{)(4Q&e3U1FV*=2N$BV1qbe<){|S!NvsmE)2K{ zn*21b%=n-Yf3yX){2)tOR_&iY`UHEMtH@5Wpdn?H|8z86oR}^f$b`>A7^Z_NKwoRz zyzEfj{!^krtc-_CmqL;OK8iplx6C0jrT7RDbEF!fIDtqKPXka-h04Y6HrL6|#)ibn zD9!l_#v{r`OW0+aX$B0BJgxbVn*y2aGL-f{XuMM_5+p!@6LOR$!73;4qGwvsJUufH zJ~WVFFqhoZ$WhaKVRO=kTe6#BuRf6T9e2!~)A!cn!b!!hirHv?DK+R(y+52hBJIn> z|L>XqdYF|KFPQ%{ABQ!xuo9rssXm2QN-*Q6JkMWPRG+0zO~dtpR+N8Ca%NJKw|a8E zLNV_Hq8S$`0>-gABgAliei@{5!zD-F%bf4-C)~pSP-#tLV0z|G#Q5bF-+guPar(n{ z{%m32yYlbIl)3?Xw_9qeK5T$ z>>7#eNEcZ^ebJ+x^XK(*ybTt)aQha~=u;fi+Ae{d>epnqU@q9?9dn9YnC^bQ!!Zboy4VD{8_&!g^#*uZe56m6}c(Z-o&^HEEnix4$SWAI+qSxB}A zR0wsl+eY8=DMVpCJmM+B>-HdHW~1_4vSz)uA7$d}9r(@+j~@OV6UM^^{_EDj-y8nw zZ;Dst-sD4FTmoApmz=mcFPK%y>*NUHXOkHOy#H_RmJd(yhc^kM+-HdvI3DeWG`#TqKat{ z%1CKM`!pB|v-5p39(o5#0rlIla_PS!Rsxa4S$8fy{fq|I`!i6L!LzWRC&?(UkGH#VpM= z4i+>~^y1B91S1GM{saI8m&niMX*s>pZk4o;tw(vUC5G?+FUkH8HBHdfq?P zCsXF=nRskFJ_LKxnA1AOMN2_%|Xc0eF4}TvQLaSTM zX`1cSeS@p|rE-CepyJZ|wR-%WWq{qM-wV@OjRte(1SlWq9f<#GI-91xcLJg4*2|Bv z6q0qr6CbFZvPo?{ymR)Svh)r31cjCwd9IzOj(gJARO-Dyp52mJhu#`p8Md?6dPpDa zwkO+WpyJM%eaqU8#TreC_k!`f2cM9xQ}l)YCTn&3++S2|_<62yX5?L|=Eybz8=7iM zFZ^9QFHY4C@_DOP3<}l&Tq8RK&>n?_t|+h5@2C-QDt2Ica!4w?#c#7@qqiYlNK=o~ z;Pj|*F+V5CC&;1{l<&VBaOqcQZZ<-a7wjldFq}`W9ro7e)l!&&_mWbpQ1-b{pUnP` z#B!|X`7{nJbl&IH530^b(fm66y7ttCF>zGz^@T}r{srkU9BUwI(kuNs$lXDEhjVvP zgtmk-zC*lkmG3$uL@S^h`XCN@Nj%7JJp{eibA2+w7W6U~#J2Q~tJ%G|p=9xOd?0US zxcTbOH-BdV>xMO34rq*70TN8#erV9x3tN@AdaB0o(9^xo)zLAycs^f{5B|b1_1-)B zQZt=~g@%QWMYpG4mW0BJS8+-A1nNx3jstAg8#B?HWF=v;nZ1U#j5#~m{#9ayY(ale zD0s8II})Wwe6LM_;rA}1l1k|Yy5aoz^HxUXoXATUPKX^8i9u*@!o5{OI3*1(;QU~ERn z6A?~^?SEnRVLDg84O=q67%n{)_l+$}eQ;E6sI%4Xmz}WG9uA8L!uA8dxR;mXY@`+nzm;;^ccPMT4V^bO`|14e-r!n!yv64{E+$IN3OI&33N{(EaJy z_|7y9G*+d(p_3$j`GTtqOUJ!~S<55+p&d5zy|hA}{h0x@JY{1y>)3Fu-hbiyH=h#t zUe{MenEfY2$Q|!2m*YuMd>paKTd9ufH6nq~?bb4bmF>!KQ#Cpzid03QqjZg_LUd5Vw z*NGxW4F?u<1I1d)w2Oa$y~+dCY^e_QQ{ zBGclXm=|PoW`*IhjKUE;c>Fplt@ro;n6=CikAF+Q0ktG|3}~fdoMJ22V;DHg5z)Et zT68+W`m-b*OJ(`M_`sKV1_z9v=C#W$a2#HuEvuq$qR-eAKxv1fZ=^JT{46ILB468eYHH&W(~qOSQuX=Hm?*4-Z9hdxJ>- zSR-y+Eq#nBor6r7hi9dgjx4Y^r!|SgUOMDhvn~y~$WgYKwQH@%M^J9~>Ql`I^p2Zv z+=2Y79o&m2!TO+SAY4B!ssfi{`ykE1<{!?ofm9tNjo-aG()5KBb+p(GSEP$QG&gE9 z1HV0J78`2wBLT}vVh+hz(!eLyE1$sC;r5+@FrJsBv(cS-WJ459mF=~k?M-9hseS^F zFyMuZ)xbVVwtQSy6l@p>dHTYnPadr+QSmEai6McDhSpFe;1+dg-QCey)XKpB8r1 zau4U$(kN=yx>&SFHBewYnos_Oti1UleI^b#+r)b6H;1+^6`VsV2?0C1R6){Iy!1iZ zXaSG6ZhQdDS!?~2WaB^LdwjI3vk>&RV8u}>*)k8%G~Jfd!LZL_-Xk~b{gKZN0^$Op zC|tv@>3o|hM!{55-SUs>(q==2f*XH6s`Ej&Oz#~GBZaTa zFSOMU7GED4y$AYoBFd)z*otq)uAoR~U~QxqaW5shTa2>q?{n z4xI!)d(oM9EpEV29Xn~AG(?(CnSiFh$}h=eR42^1kyuo77-3Hy*+oC%T-_`s)WwZT z1u;<}L*CWHD`Ohul3vzN&5!Lf$6@UPmKriM3(C5}PZZprR35j>7~lD=K^GJ2(i`LE z7nqGVlC6f1HjL|$C>U**L7KDBZf_6c3E(q2@9fS@1g50MYJYaFndepBK)@mz-`m;t zSk~kyGi1?fYo97jfnAnuOBL*2 z!7$R^s0Y=_xywiTl!4W^$PjoSCcqkhCxugIGHFhLrwp9CW_}7TQnT%@D*GdqEE^%C zp(jh1%t@h>0OMgJC%GN$p0)*)O(-CZ^nQp5GIR8Zc0OjJmdNniY>=2#z~wb)Oz2em z^l^TF>*&#ku-STkoWP>{LXEUTx&j@#&e_c>cXm9KD&dz1R5qZg1dxD7igjAV^%UjV zmzERW`kT)Ftcxp4j>}SPSgAe{!BL%)4#>KsjB;bvMHn^F{KwN#GcLS@ylukE_aTV$Q z)n)M|(!`37lCg?p*;`zK;omFM$6GB<-g=bls%@dR-(frua7Xj>Q+}k1wRaBVP-ur( z_0P1U@2l%+eBOrB}Xix>-p~RMc2Jci^v*L{yZ1HYAZ8P9D~o7JF?`OxBxwL>>@!m$I~ z>z$l{BMFeo>qw-JiyhtKy|G8swEQ^7^_QD(S@blzU%NIlF3%qfh8ddeP|0O}_x%wO zrIZ}804yY>N}5H8Hp27!0QCLW`e}oVuGc>Z~5!noe3j}3sixVG<2fZ05QUN+TV%%j0()EC1_>R)z$;}*y^v~ zODv?T(WuE8?33DMXE(WmJ&=A!axnTP^DxNsk$i4zkV@qec!8Gag30|G#^cHB!O&-# z83|8FHRT*_tF8&LOqZM-ew}T(N+iHUV{XjL^@1p7yk_y~@TPhWBN$2VrIwpTyVC@ z9lFDzk9D+8Qb{E|=q!QQq`(iIljfiCG_-g*&)$X9H8mDGaM{28?1Qn=5n>DR@j)K= z37#w&Etc4o!dr^!*)&my@$iAaH}{G8gq}m{8FGH^Z5p4ka-A}h6CEANTjIYYSC5>k z-N2aX9@(CN-riTnH(F&zOD1v_GdMxrx(d#q#lvDW;7dBW%Ii1GpUxAk>nH=^TR4yr z-qS=L(331IG4411TFHMM%(r#C?w~4ouJe$hyY&uam)U($f`M7SYY!5GyW`d3-s(0)W}qZdlu8Spr1N8|H%evAyTLD z4diKXNSVHYf#}WqfPAyieP;Z7Y(z&4)t(!>*Hrg%Xv|;bwiv>#EU^zQA@wvvzrMZT zF3rV`3ez`Xa(H;~shqHXxs^MzSkY(HAgi~%sw$fiqO3M&1ww!Jw`hZdi%K8+WVZNL z7Tie^gM#pPi+xRg+9g4Y^f?R{U$ki}sHcQ*;~Av@HGkt$0(sp`-I0Z{BIKg+;e!wY zaInM_+D3SbJQPv9fM{u;bzwDf5tZo!Eo9h$^CDxury z>Apa6xjNxlO6TI1ERjDre-P#p?ap{igmncC_Ps_ z2+TEeL52(is)%V2S!5;tI(2{9r>i8SnbDlg5QLN|PJ)FLTBnoRXYq&;WfNiYbnzJp+4oc zaS$#9q2p~sx$t!q&GSK=f6VtAHng*HN7FE5K|~#qW@j2Sda2ZhpWZIFGp3u8O9A5v zBb#e*p;!l{3cY&GJZp93-9n*8^;!Cyd(Nh#Q6Qdv$E*Ttk9N|K9{4LKVNm~y=<4Mw zp&R@1LjRblu=)(U+%4#)`ZhKS0jF8rL#7b+w)cvq;O<{)#lq6{+ zM;=tFM&pd)4N=Q`T3TT)CLJj&I^sciR?S7L>CVBG?WEg?xS_cNhoy#Bp{ZPATGUf) za>2EHc zRpd(yc|dERZsNE3(B%N=C<`jPyM3_vOVtulG@9s1wB**_{tZG!#(WIk>12BA=1ib> zDgd4k6s4N1-j5ccek*|~!scSuzTs<0!&V!K_))$osEKKZ36pg`Md6#y)Z$s4a55vB z=FtL{Wa0Dor;}*poD;#@aNzbGO63EPG-dr94x7 zQoCSWX**lU0b?1lltXK+ld`!st^Mu6EFILmrdd!lfSWaan50Gk^GgPB&E49{C=lUY0$|{t{)R#Q6 zTvA1g*6loWjBt0V@Y~CL94&3GTSnEA+p@D%?=5+noM^NrZsyXNVi-i$3z5BO7+>_@ zI{OgT{?Pp(F;+>{vHY>dE?`<@>E;YAwB%;VB$xepeR@NKE{qQFmD8SNeO%M5xO}h< zP;NrA|L0n=%F0S0e2f1gr=SZSF^fqa^-MN!-pYJNI8Sl#ChHAD7Ig+=a_ac2xKA%x zxwA~UFGRL{vb=2Od0J^`vR>^Iy>Yraxo=L%EprzOSe$n%`EtlHToDoukQiyLD=4@Q zRv(WG#Ebc?&tKGI1nWP)DHizgfv>|I4<^T-A|n=GsOX|rO0bex#O~U#gDJR}*$2~= z39;=}P=Ov?2&LpJTcNDD+4g|tQ?w39b&p@RoZnqV=5@}9 zp>f2}z0$?liS9+F8P3{NXl%gJBa(gDWaWu{$uQ=Ky|L!4u_@GgHIpg-P>yNqc9Fwg zC%Ym53Jo~42Ntes&OM*E+9T`7MQ1aU1*)R@^Vei#Ic`6LZt)zw1(9au03TLs2 zNsKDq9$4UaXFCrM#%`SyDXmq86X=+|HmzUO_pPw69L8<4_qiZY`80)yIwqK&M5FlP zAX(Lp9ooe|KXH>@Mql&lyS6>MstmA5p^YScHN6Hp%R-aj^O)>(rBfEDsFyzlM+g1; zoPYj^>|Mpm39;P5n2>oFEByQI=Ntd9YaWr%$kDsct<20q;N@u loadCurrentUrl() async { - final resp = await http.get(_urlSource); - if (resp.statusCode == 200) { - _radioUrl = resp.body.trim(); - print('Loaded remote url'); - } else { - _radioUrl = _fallback; - print('Request for current streaming url failed, using fallback url'); +Future loadStringFromUrl(Uri remote) async { + try { + final resp = await http.get(remote); + if (resp.statusCode == 200) { + var ret = resp.body.trim(); + print('Loaded remote url: $remote - $ret'); + return ret; + } else { + print( + 'Request to load remote url: $remote - failed - Status Code: ${resp.statusCode} - Body: ${resp.body}'); + return null; + } + } catch (e) { + print("Exception - unable to load remote url: $remote - $e"); + return null; } } @@ -35,21 +41,21 @@ final _urlAbout = final _urlAboutIOS = Uri.parse("https://generic.ything.app/ything_radio/about_ios.txt"); -late final String _remoteAbout; +late final String _displayAbout; Future loadAboutUrl() async { - final resp = await http.get(kIsWeb || !Platform.isIOS ? _urlAbout : _urlAboutIOS); + final reqUrl = kIsWeb || !Platform.isIOS ? _urlAbout : _urlAboutIOS; - if (resp.statusCode == 200) { - _remoteAbout = resp.body; - print('Loaded remote about'); + var about = await loadStringFromUrl(reqUrl); + + if (about != null) { + _displayAbout = about; } else { - _remoteAbout = _fallbackAbout; - print('Request for remote about failed, using fallback about'); + _displayAbout = _fallbackAbout; } } -String getAboutText() => _remoteAbout; +String getAboutText() => _displayAbout; Future setupListenHandler() async { _listenHandler = await AudioService.init( @@ -96,10 +102,20 @@ Future setupListenHandler() async { ListenHandler getListenHandlder() => _listenHandler; -UrlSource getUrlSource() { - return UrlSource(_radioUrl, mimeType: "audio/mpeg"); +Future getSource({bool fallback = false}) async { + var radioUrl = fallback == false + ? await loadStringFromUrl(_urlSource) + : await loadStringFromUrl(_fallbackSource); + if (radioUrl != null) { + return UrlSource(radioUrl, mimeType: "audio/mpeg"); + } else { + return getInternetError(); + } } +Source getInternetError() => + AssetSource("audio/internet_error.mp3", mimeType: "audio/mpeg"); + Future startAudioSession() async { return await _session.setActive(true); } diff --git a/lib/ListenHandler.dart b/lib/ListenHandler.dart index 5d72fe1..7987833 100644 --- a/lib/ListenHandler.dart +++ b/lib/ListenHandler.dart @@ -5,8 +5,6 @@ import 'package:ything_radio/Globals.dart'; class ListenHandler extends BaseAudioHandler { final _player = AudioPlayer(); - final UrlSource _radioSource = getUrlSource(); - setup_player() { _player.setReleaseMode(ReleaseMode.release); _player.onPlayerStateChanged.listen((event) { @@ -64,10 +62,22 @@ class ListenHandler extends BaseAudioHandler { @override Future play() async { + print('Starting playback'); if (await startAudioSession()) { - //setSource followed by resume does not work on Android or web - //play works everywhere though - _player.play(_radioSource, mode: PlayerMode.mediaPlayer); + try { + //setSource followed by resume does not work on Android or web + //play works everywhere though + await _player.play(await getSource(), mode: PlayerMode.mediaPlayer); + } catch (e) { + print("Exception $e - loading fallback"); + try { + await _player.play(await getSource(fallback: true), + mode: PlayerMode.mediaPlayer); + } catch (e) { + print("Exception $e - playing internet connectivity problem"); + await _player.play(getInternetError()); + } + } } } diff --git a/lib/main.dart b/lib/main.dart index 8274aef..5fe379b 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,10 +1,11 @@ +import 'package:audioplayers/audioplayers.dart'; import 'package:flutter/material.dart'; import 'Globals.dart'; import 'YthingRadio.dart'; Future main() async { - await loadCurrentUrl(); + AudioLogger.logLevel = AudioLogLevel.info; await loadAboutUrl(); await setupListenHandler(); runApp(const YthingRadio()); diff --git a/pubspec.yaml b/pubspec.yaml index f4fe0c6..3a82fbd 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -73,6 +73,8 @@ flutter: - assets/images/app-background.jpg - assets/images/app-background2.jpg - assets/images/app-background3.jpg + - assets/images/app-background4.jpg + - assets/audio/internet_error.mp3 # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/to/resolution-aware-images