From b4956607d392fecf37cf47147598582a19a56176 Mon Sep 17 00:00:00 2001 From: ske087 Date: Fri, 22 Aug 2025 11:12:42 +0100 Subject: [PATCH] Fix syntax and indentation errors in tkinter_simple_player.py, improve stability of settings UI and video playback --- tkinter_app/resources/log.txt | 77 +++++++++ .../tkinter_simple_player.cpython-311.pyc | Bin 117855 -> 115854 bytes .../virtual_keyboard.cpython-311.pyc | Bin 17542 -> 17542 bytes tkinter_app/src/player_app.py | 0 tkinter_app/src/settings_screen.py | 0 tkinter_app/src/tkinter_simple_player.py | 153 ++++++------------ 6 files changed, 124 insertions(+), 106 deletions(-) create mode 100644 tkinter_app/src/player_app.py create mode 100644 tkinter_app/src/settings_screen.py diff --git a/tkinter_app/resources/log.txt b/tkinter_app/resources/log.txt index 5576e56..5652d5b 100644 --- a/tkinter_app/resources/log.txt +++ b/tkinter_app/resources/log.txt @@ -1184,3 +1184,80 @@ [INFO] [SignageApp] python_functions: Starting load_config function. [INFO] [SignageApp] python_functions: Configuration file loaded successfully. [INFO] [SignageApp] Application exit requested +[INFO] [SignageApp] python_functions: Starting load_config function. +[INFO] [SignageApp] python_functions: Configuration file loaded successfully. +[INFO] [SignageApp] python_functions: Configuration loaded: server=digi-signage.moto-adv.com, host=tv-terasa, quick=8887779, port=8880 +[INFO] [SignageApp] python_functions: Starting load_config function. +[INFO] [SignageApp] python_functions: Configuration file loaded successfully. +[INFO] [SignageApp] python_functions: Starting load_local_playlist function. +[INFO] [SignageApp] python_functions: Local playlist loaded: {'playlist': [{'file_name': '1307306470-nature_wallpaper_hd_hd_nature_3-3828209637.jpg', 'url': 'static/resurse/1307306470-nature_wallpaper_hd_hd_nature_3-3828209637.jpg', 'duration': 20}, {'file_name': 'wp2782770-1846651530.jpg', 'url': 'static/resurse/wp2782770-1846651530.jpg', 'duration': 15}, {'file_name': 'SampleVideo_1280x720_1mb.mp4', 'url': 'static/resurse/SampleVideo_1280x720_1mb.mp4', 'duration': 5}], 'version': 5} +[INFO] [SignageApp] python_functions: Finished load_local_playlist function successfully. +[INFO] [SignageApp] Found fallback playlist with 3 items +[INFO] [SignageApp] python_functions: Starting load_config function. +[INFO] [SignageApp] python_functions: Configuration file loaded successfully. +[INFO] [SignageApp] Initializing with settings: server=digi-signage.moto-adv.com, host=tv-terasa, port=8880 +[INFO] [SignageApp] Attempting to connect to server... +[INFO] [SignageApp] Fetching playlist from URL: http://digi-signage.moto-adv.com:8880/api/playlists with params: {'hostname': 'tv-terasa', 'quickconnect_code': '8887779'} +[ERROR] [SignageApp] Failed to fetch playlist. Status Code: 522 +[WARNING] [SignageApp] Server returned empty playlist, falling back to local playlist +[INFO] [SignageApp] Loaded fallback playlist with 3 items +[INFO] [SignageApp] Playing media: 1307306470-nature_wallpaper_hd_hd_nature_3-3828209637.jpg from /home/pi/Desktop/signage-player/tkinter_app/src/static/resurse/1307306470-nature_wallpaper_hd_hd_nature_3-3828209637.jpg +2025-08-22 10:13:23 - STARTED: 1307306470-nature_wallpaper_hd_hd_nature_3-3828209637.jpg +[INFO] [SignageApp] Successfully displayed image: 1307306470-nature_wallpaper_hd_hd_nature_3-3828209637.jpg (Original: (1600, 1000), Screen: 1920x1080, Mode: fit, Offset: (96, 0)) +[INFO] [SignageApp] Starting Simple Tkinter Media Player +[INFO] [SignageApp] Playing media: wp2782770-1846651530.jpg from /home/pi/Desktop/signage-player/tkinter_app/src/static/resurse/wp2782770-1846651530.jpg +2025-08-22 10:13:35 - STARTED: wp2782770-1846651530.jpg +[INFO] [SignageApp] Successfully displayed image: wp2782770-1846651530.jpg (Original: (3840, 2400), Screen: 1920x1080, Mode: fit, Offset: (96, 0)) +[INFO] [SignageApp] Playing media: SampleVideo_1280x720_1mb.mp4 from /home/pi/Desktop/signage-player/tkinter_app/src/static/resurse/SampleVideo_1280x720_1mb.mp4 +2025-08-22 10:13:38 - STARTED: SampleVideo_1280x720_1mb.mp4 +[INFO] [SignageApp] Video dimensions: 1280x720, Screen dimensions: 1920x1080 +[INFO] [SignageApp] python_functions: Starting load_config function. +[INFO] [SignageApp] python_functions: Configuration file loaded successfully. +[INFO] [SignageApp] Application exit requested +[INFO] [SignageApp] python_functions: Starting load_config function. +[INFO] [SignageApp] python_functions: Configuration file loaded successfully. +[INFO] [SignageApp] python_functions: Configuration loaded: server=digi-signage.moto-adv.com, host=tv-terasa, quick=8887779, port=8880 +[INFO] [SignageApp] python_functions: Starting load_config function. +[INFO] [SignageApp] python_functions: Configuration file loaded successfully. +[INFO] [SignageApp] python_functions: Starting load_local_playlist function. +[INFO] [SignageApp] python_functions: Local playlist loaded: {'playlist': [{'file_name': '1307306470-nature_wallpaper_hd_hd_nature_3-3828209637.jpg', 'url': 'static/resurse/1307306470-nature_wallpaper_hd_hd_nature_3-3828209637.jpg', 'duration': 20}, {'file_name': 'wp2782770-1846651530.jpg', 'url': 'static/resurse/wp2782770-1846651530.jpg', 'duration': 15}, {'file_name': 'SampleVideo_1280x720_1mb.mp4', 'url': 'static/resurse/SampleVideo_1280x720_1mb.mp4', 'duration': 5}], 'version': 5} +[INFO] [SignageApp] python_functions: Finished load_local_playlist function successfully. +[INFO] [SignageApp] Found fallback playlist with 3 items +[INFO] [SignageApp] python_functions: Starting load_config function. +[INFO] [SignageApp] python_functions: Configuration file loaded successfully. +[INFO] [SignageApp] Initializing with settings: server=digi-signage.moto-adv.com, host=tv-terasa, port=8880 +[INFO] [SignageApp] Attempting to connect to server... +[INFO] [SignageApp] Fetching playlist from URL: http://digi-signage.moto-adv.com:8880/api/playlists with params: {'hostname': 'tv-terasa', 'quickconnect_code': '8887779'} +[ERROR] [SignageApp] Failed to fetch playlist. Status Code: 522 +[WARNING] [SignageApp] Server returned empty playlist, falling back to local playlist +[INFO] [SignageApp] Loaded fallback playlist with 3 items +[INFO] [SignageApp] Playing media: 1307306470-nature_wallpaper_hd_hd_nature_3-3828209637.jpg from /home/pi/Desktop/signage-player/tkinter_app/src/static/resurse/1307306470-nature_wallpaper_hd_hd_nature_3-3828209637.jpg +2025-08-22 11:10:25 - STARTED: 1307306470-nature_wallpaper_hd_hd_nature_3-3828209637.jpg +[INFO] [SignageApp] Successfully displayed image: 1307306470-nature_wallpaper_hd_hd_nature_3-3828209637.jpg (Original: (1600, 1000), Screen: 1920x1080, Mode: fit, Offset: (96, 0)) +[INFO] [SignageApp] Starting Simple Tkinter Media Player +[INFO] [SignageApp] Playing media: wp2782770-1846651530.jpg from /home/pi/Desktop/signage-player/tkinter_app/src/static/resurse/wp2782770-1846651530.jpg +2025-08-22 11:10:45 - STARTED: wp2782770-1846651530.jpg +[INFO] [SignageApp] Successfully displayed image: wp2782770-1846651530.jpg (Original: (3840, 2400), Screen: 1920x1080, Mode: fit, Offset: (96, 0)) +[INFO] [SignageApp] Playing media: SampleVideo_1280x720_1mb.mp4 from /home/pi/Desktop/signage-player/tkinter_app/src/static/resurse/SampleVideo_1280x720_1mb.mp4 +2025-08-22 11:11:01 - STARTED: SampleVideo_1280x720_1mb.mp4 +[INFO] [SignageApp] Starting VLC for video: /home/pi/Desktop/signage-player/tkinter_app/src/static/resurse/SampleVideo_1280x720_1mb.mp4 +[INFO] [SignageApp] VLC finished: /home/pi/Desktop/signage-player/tkinter_app/src/static/resurse/SampleVideo_1280x720_1mb.mp4 +[INFO] [SignageApp] python_functions: Starting load_config function. +[INFO] [SignageApp] python_functions: Configuration file loaded successfully. +[INFO] [SignageApp] Playing media: 1307306470-nature_wallpaper_hd_hd_nature_3-3828209637.jpg from /home/pi/Desktop/signage-player/tkinter_app/src/static/resurse/1307306470-nature_wallpaper_hd_hd_nature_3-3828209637.jpg +[INFO] [SignageApp] Fetching playlist from URL: http://digi-signage.moto-adv.com:8880/api/playlists with params: {'hostname': 'tv-terasa', 'quickconnect_code': '8887779'} +2025-08-22 11:11:09 - STARTED: 1307306470-nature_wallpaper_hd_hd_nature_3-3828209637.jpg +[INFO] [SignageApp] Successfully displayed image: 1307306470-nature_wallpaper_hd_hd_nature_3-3828209637.jpg (Original: (1600, 1000), Screen: 1920x1080, Mode: fit, Offset: (96, 0)) +[INFO] [SignageApp] Loading configuration in enhanced settings window +[INFO] [SignageApp] python_functions: Starting load_config function. +[INFO] [SignageApp] python_functions: Configuration file loaded successfully. +[INFO] [SignageApp] Config loaded: {'screen_orientation': 'Landscape', 'screen_name': 'tv-terasa', 'quickconnect_key': '8887779', 'server_ip': 'digi-signage.moto-adv.com', 'port': '8880', 'screen_w': '1920', 'screen_h': '1080', 'playlist_version': 5} +[INFO] [SignageApp] Configuration values loaded successfully in enhanced settings +[ERROR] [SignageApp] Failed to fetch playlist. Status Code: 522 +[INFO] [SignageApp] No playlist updates available +[INFO] [SignageApp] Playing media: wp2782770-1846651530.jpg from /home/pi/Desktop/signage-player/tkinter_app/src/static/resurse/wp2782770-1846651530.jpg +2025-08-22 11:11:29 - STARTED: wp2782770-1846651530.jpg +[INFO] [SignageApp] Successfully displayed image: wp2782770-1846651530.jpg (Original: (3840, 2400), Screen: 1920x1080, Mode: fit, Offset: (96, 0)) +[INFO] [SignageApp] Playing media: SampleVideo_1280x720_1mb.mp4 from /home/pi/Desktop/signage-player/tkinter_app/src/static/resurse/SampleVideo_1280x720_1mb.mp4 +2025-08-22 11:11:45 - STARTED: SampleVideo_1280x720_1mb.mp4 +[INFO] [SignageApp] Starting VLC for video: /home/pi/Desktop/signage-player/tkinter_app/src/static/resurse/SampleVideo_1280x720_1mb.mp4 diff --git a/tkinter_app/src/__pycache__/tkinter_simple_player.cpython-311.pyc b/tkinter_app/src/__pycache__/tkinter_simple_player.cpython-311.pyc index 789a54aa71648914c6a8163592505c3ab1285c3d..7c6c5fb0454acaba207cafb986c321332d3c6798 100644 GIT binary patch delta 9218 zcmbta33yaRw(fJgb9+lCO~_6{IwXWNNoQe|oe&dbOGH_9AnBw#BqZsM)tx{h5N2SW zfCzyLQ^1S}BctFb1Ji0N?tsqVHXUpvHi|lLe2Qy$gUGnPbE>l-;=J#Duetee-KtZk z&N+4J)VXzecb9g{Ms3uCCX+#hzfXz|)}C8(G^)|gC&YqYy9?{?Qr*Ruu7RP-^HJu= z4X{B~BROEbZndOzj*5?5B{`&r)elH2)gLAPOBW1Q)&^o5tr2ZAZ*H)+T3YHHPPe6| zuEA+(_SCtSS(;kCwQiTKrJ>rkg4vszoXk?=W)|kIYW8?7wRYxMVP{T@y}H`j;AD1h zo!gaHO``Sw^jH{(fB)R8R;hMMT%}h!;}SFu*eG+$JrJvRNDftlv|6=_zwjg^#5&Xt zjU&P#JG2g+L;rvl1=T9&7Y#vmqNLRl-+u@aV>ikV05;%X__tcUN>c1kCGgD;!2mw_ zUPx4q*au+o`2!Fe?=bwB8dQ1}(wpB-P@cOjIvG^1ybP5$zL%Lwm8oLst2JIw(oe-f zBrm%Mk_M?(Yu0F7I)}KgfEB8h>cy%RK%BVw8HgwObgLs)MXXXSkK*ITz+h>)nZG|8 zVq=#N=w)4_Zc#CC#d&{Lvd!fvS>^5VB){_M_i-ABsmD-xKPP1`bCqg28Cv`tQU6xz zjoRh0$~f&{-3Dz9IHK3YaJ&v|GQ4)=jM82A!DR7A}x#A8T9BZ6GgWY7n%`o zjJa7zd#l%t>)8>~c(A}ep^k&7qrqOY*o#usIU1Z+9UFzKETpUJl~fMP$cAGz8%y*N zVi1-?6=Sf%qeHNW-`ch81|re+*t4zRS_>zWJ<|}-p50P{sSVyS$L}x(Ql=egMZl}m zTpTnP2h7D?=Hw0o{p%Vu_`ZpICLS~dM$P)`qQJtXfyz6&RVpvcknlE3nkQXUsZ!=k zmjrg`x{}h*CXG0qG@>(UR4{2&huoEDX+N7d{B+{*gX20AM+Xx}cSLlVL2LG!SHc^KAl<96dV(+*RI=^bH#yLD>nITto3xP^|$qT0Bb(C}^r0g4bAn8Ebk&H*JkLEu=^5nQ+@w|X#ejtIauEf-L zViR}F+~wI;zN5UOyjzbP?vO8mvvf~)v3!4>aqj6>~1Mh z--a{)@9@hJDt$~)m$*-RL=(`B?$nJA>PDZ{O*pNa(5agg)J+QXULtZ-77vJ-D~hk_)f4ffdb74qWgRB4Ae3Fngo3EgM%}oHDOvAdL3awtOrN z3=OEDDBMHjq?n)#*pi^QS_i-+-`dt#2?~{+cecWGU-YUbEk3MWm#q0(8gEhVTW3uR znQopjyP{}8(Tv$e(`J`2+^AI{jl0R|Vh>|c`Mfb*vAdGDufI7Wr1p53GJpLjLr8Yl z)L_J7bCizt#c+!+xc*5Elqy>`Cd)G@e#}%3Z%lz%$}1Zu!v>#W(>ahiMTpy!=uIWQ zg3Wpf_WQ8W=0VR5iMTy#PkiL_A$@~2PlJE5I-_{v-Vh7elgKYOb`Ns)rDDr)II0B;AW4#sF z{o&g|MSo-=n#_LWj{`*yH}(i=N>*?F%r>HGgw3(hsfI8pMXI5yTO1bxB0kr#GKlxXUyny&F zRDO5L4vUrVPh~-qGW6vv@G7%ko&pd1Hov@0omfRQVrMjy^0d_nL-3=^Ay%38`Yd=_ z+4B17v{Ixi!)Xt@B6XUDfTXmov5%DYzfDC?d;V`}5*$$8>%0+8`G%gp4dgN+ovZx% zjbTu)Jn}|j9!)h{L$IHE-cLY!GE#^MaWbhiiW)vs{`p2aDjXN=j!ub~+^y<^iM~N+ zS|#~zB&}BSf>?<49X>lBz^`cDS}I>64qqy@Z{<`t`LS?W zS#y4n`3a&Dq)$@mm~!a6UHU-ni+uMjz4RR@AAU49eLJ>Xh(uWqso9+*(k>!hMWyel zq)`@MNCUIddLd`z4_FbB?bY787AI5D5>g|ejm%VzM`$zNXlM0#^GYf1pr4wRvlr4v z_cgPn$hViK#N}nJOePN6P;^b5v%yhiudZLl+|4cri&t_!9#2Xw`#2M}DVsmO9TerG zkBj3;J}Xe>(c0iVB#C^JZC8pu8D%vfuaLUY-o%nf{z`(&q(l{!=+%ThO^?qgdp~(C zdni#G8trwiaF}GrNxf*1q*heBU0!U#(0Ec&J{==p!M3(ko?Z^|rWJJ#+$B8G8eB&M zl>h!Tv;94tX>0VR=s;q2SH`dd6ArEkW=!tN9NLwUzi;BciQQV2KJlVTtuMSp&@Dix z(np2+KdGNQ1h_yNLetuIFNcHCKZEA;k_Q3HNl+Hz~JfEr6Fl! zE~+&8>2OJ4cNh)Ix1SAb?^mzClxpkKFrPHcCk^wvdo|o;>dMYVN#+Ezr(JEH>;too z=z^K!u2OnP)`6UZjlm%kyHagknM4p3%$(94EmYU)i@}Wm~+S zCR2xQ>8-=0J?y&ZJdVrn%OWaI5mTqIZxZ-tMu-8Ia`#t7xJ+LA>O2%H4_|o-vG!k% zA>`t09eK*1snkL)p{a6vYZ)yRObB)=pZ_b-xPt1T72R*AGT`fYFeuqyH_7B&p;%r} zj*;chU&ol9r7p&B1R1S#eq9ffl}X9k4yF7H9gHy!L>6N89n$c06U0hvH!sygiA?zdbMkF^7;j!qke1fbHwP*m_eStaBNW1VzTF5pFp@uOgd*t!4Tngqb@P#U%NCnU z3o$u|!lBwCR2(KjH8jXk(p1fM^39R3dLY$@bbU?Rx5_|P_77?9hdAy&JK*5bPw zrQ@5i{`P2iFd~)0aG6zRcT&HZG+LM&v25qXagYU!FOP#^($^Zl5(lknvVT-kzx~G~ zK^vO;XcCMC7r&4M%aVUq{snw_GAuEMg`^Qz^V7*VTQ>e(G8BO1&l?2!Me?jew$OTm=Y5Il;t&2)0mecz7tmRp=P%;~AM%yuvHFyWxz1OKlfFg#sM zz_-MLT*Rsu@s&*?ZI=+-#|tyy#syQ6C(RBKE~NTJ1Z7xTW{tZlR$fm%F*6RL7xS`^ z#499tfxnUgY1X+^zJ=f>BASP#5G=-bN3m~SZIFSPFbDFuJriP- zLQIvr*<0bYS5-J&we+sV zKPt_l#~*;N8w-V6i5|WM{?u3)EsMq2%rB3H8*;^La^g}&ASSYJ4nszdy~Rn}Tut3F zwus+$1Ed&VAgRQLc|ZT<4KUm!OrQ^&;1Yl02FM*$Ny8mN2$@*jvRZFNRkPRYc6r!e zfWJQl;^hKtYa1%orWpgL*WD;KQ|4~)Z15M2gFi)>MNktVNob$-n<T2Z z&mn}gn55XfUdCdGR*WmWf!1j#+U{`hUmu%EVreLDKyo& zn$U+ucJ^9?zo`^Ps;Bg;FC-M|i+Q0F9icL={|XwF-ZQR>N0k0CFaP@t7&cN&P8C&< zXNHW$wa)7Luro0+KXQ-XkwRf+eBw;VmUoeKgTujp?M%=~mm~a}X2K%LC}a@x@H_u! zv%wB9ke8RifrKE5@hXmm{xp_`e30NQHWTXS111J zVwehTVkHm@6J+_v+y?cMj&^l?#ayC%J}8MF{{_4VK#brb~%?k)#Y4-wc{kHQS80 z5Y(ZI=&R91Zs!ZC;aqwri7hCk9*XMli*)$#gb>^lzz! z_W_-&X*r~&KTqBImVC%mi=TBW>Yc4sZVX@;C7bw><1Qe#<7AR%}#{ZgT6r;0-;_AlhtHca{A zd>qeh#ALhKKcx}IOS0I;e$U(8(2^^5Dw^&?YIckmi}XP(u%8^O@bo5_06Y1TCYYF3 zMZ}b5FbBakeJ}GTnqU~5=kGOv74G&M?tr4m_US}!@6iH<+Jth+Dz`Br`h10YO{I20-E%*|$lSt_ZYf>n#_iI_j z)nCizvE9_uSZ%Mab%qc5*&eDf*qgoX3WkSet?U@ru7Nyb*mg9xT0V6RxCZIT_y&TX z+UwLBj6Em#H*4VAeHQHe~&qNqeBV$oFUn}>OLBA|1w ztn+v)-1Y25B=Fm|Kq5@**Z$utem$K9_b>TfTOl77bN^Pj$@l~f-IF01I-nT5ysQJq z@$+RJkS2X1`!{qzi*At!$dn+IvMp$;3%|kQg~4Pck@|D2o5vR5b2F-;`up#GeMn-5 zk@p1)(TKTL$i%w|_7L=>7YlYnTD!<;kCG@^2qCF_7Skf1GV8!_y!BHDA?0*pH;bTu zd5Ke@@PQD~nTSs%kyH^>6HrbOl8Z~q=9S#SM9NPGj$*>CTE;K!#?52|^*h01_h9f& z;gj~D$L09ld*H)}b~c%)htLdNV+fW(m6-(BHN?G}*-&bfi1{@Z$fP>4%M2ruYy#4s zS+P`Rjp@_9{r|5#8&2H&G)JYyYd|XM6^az+(kmUi?8pDq~0-47CXndK!`v?Z&FS+(G zq{31@^e{|@C%EGBc{ApF(bl%kbokV zh@~vTmxya3mP{Z|_y|ex%?8unW=z=K4kt?{;r^3)ia@oLPkbC~FrF`e9Hzh`{?Ox? z1N_PV`r~jyHoT3agn*Ty4S)L#RF*8JXFYS;9SwLA=n1oVfX2BdwV_M|KXf>qVvt_b z{ey(|@~O{49u#u-vydvC(fYSM3%^&(v_RUD_<-Y(z~>xC8UDcUI1VeN&$Rwej>8Y2 zEkuGcb}PSl5}eXkTE)DofNyvaX0{)v@o5(;wWhPrX^1Zfx(UXSo+$)$T*-2Xl#WUm zBd`(V5zs3tDZ+Ut^b3U;0(as{Heb}Zk#xh z7oWX#)KyIBdHyXn*+S~-mJ!T`yhCdICMCW^F&z!H2uVZ68I4VD<`o~k*{6K|DJYY^ z0{(|nkY!CI(c+0z2=rqi@jnJMx*g38&dKa{|D{uK0ov_RklwAjK3){{m#%KTDYf1V khHlmM@uH}|^fRpc4*FGR-_WvXAu05#tJ2hx(fN&o-= delta 10585 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 diff --git a/tkinter_app/src/__pycache__/virtual_keyboard.cpython-311.pyc b/tkinter_app/src/__pycache__/virtual_keyboard.cpython-311.pyc index b664ca894768fddb46ad109378af99c1b8c9c8df..4bc97e38898941b40a45cb75e574fb6bb006d244 100644 GIT binary patch delta 89 zcmZqcWNhnX)*5BV8yO>R^#)xE`7UDN@Tzr|Qv k)Cs0*ilzYRUyN2oQ^B;-Ek>JLjCQve?Qd;X)<~8C0RPb(-~a#s delta 89 zcmZqcWNhnXR^#)&0d-UDN@T|HW8a i)Cs0*il%^RtD>o3TIm;~%`Zl~UySy@HY;l+%K!j2NFG7} diff --git a/tkinter_app/src/player_app.py b/tkinter_app/src/player_app.py new file mode 100644 index 0000000..e69de29 diff --git a/tkinter_app/src/settings_screen.py b/tkinter_app/src/settings_screen.py new file mode 100644 index 0000000..e69de29 diff --git a/tkinter_app/src/tkinter_simple_player.py b/tkinter_app/src/tkinter_simple_player.py index b43a3dc..3350f7e 100644 --- a/tkinter_app/src/tkinter_simple_player.py +++ b/tkinter_app/src/tkinter_simple_player.py @@ -533,88 +533,34 @@ class SimpleMediaPlayerApp: self.auto_advance_timer = self.root.after(5000, self.next_media) def play_video(self, file_path): - """Play video file""" - # Clear any status text and hide status label + """Play video file using python-vlc-wrapper for robust hardware acceleration.""" self.status_label.place_forget() - - # Check if PIL is available for video playback - if not PIL_AVAILABLE: - Logger.error("PIL not available - cannot play video") - self.status_label.config(text="PIL/Pillow not available\nCannot play video files") - self.status_label.place(relx=0.5, rely=0.5, anchor='center') - self.auto_advance_timer = self.root.after(5000, self.next_media) - return - - # Use OpenCV to play video in a separate thread - def video_player(): + def run_vlc(): try: - cap = cv2.VideoCapture(file_path) - - if not cap.isOpened(): - raise ValueError(f"Cannot open video file: {file_path}") - - # Get video properties - fps = cap.get(cv2.CAP_PROP_FPS) - delay = int(1000 / fps) if fps > 0 else 30 # Default to 30 FPS if unknown - - # Get video dimensions - video_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) - video_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) - - # Get screen dimensions - screen_width = self.root.winfo_width() - screen_height = self.root.winfo_height() - - # Ensure we have valid screen dimensions - if screen_width <= 1 or screen_height <= 1: - screen_width = 1920 # Default fallback - screen_height = 1080 - - Logger.info(f"Video dimensions: {video_width}x{video_height}, " - f"Screen dimensions: {screen_width}x{screen_height}") - - while self.current_index < len(self.playlist) and not self.is_paused and self.running: - ret, frame = cap.read() - - if not ret: - break # End of video - - # Convert color from BGR to RGB - frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) - - # Convert to PIL Image for better scaling - try: - img = Image.fromarray(frame) - - # Scale video frame using the scaling helper - final_img, offset = self.scale_image_to_screen(img, screen_width, screen_height, self.scaling_mode) - - # Convert to PhotoImage - photo = ImageTk.PhotoImage(final_img) - - # Update UI from main thread - self.root.after_idle(lambda p=photo: self._update_video_frame(p)) - - except Exception as img_error: - Logger.error(f"Video frame processing error: {img_error}") + Logger.info(f"Starting VLC for video: {file_path}") + import vlc + instance = vlc.Instance('--no-osd', '--no-video-title-show', '--intf', 'dummy', '--no-video-deco', '--no-embedded-video', '--quiet') + player = instance.media_player_new() + media = instance.media_new(file_path) + player.set_media(media) + player.play() + time.sleep(0.5) + try: + player.set_fullscreen(True) + except Exception as e: + Logger.warning(f"Could not set VLC fullscreen: {e}") + while True: + state = player.get_state() + if state in [vlc.State.Ended, vlc.State.Error, vlc.State.Stopped]: break - - # Wait for the next frame - time.sleep(delay / 1000) - - cap.release() - - # Schedule next media from main thread - self.root.after_idle(lambda: setattr(self, 'auto_advance_timer', - self.root.after(1000, self.next_media))) - + time.sleep(0.5) + player.stop() + Logger.info(f"VLC finished: {file_path}") except Exception as e: - Logger.error(f"Error playing video {file_path}: {e}") - # Show error from main thread - self.root.after_idle(lambda: self._show_video_error(str(e))) - - # Start video player thread - threading.Thread(target=video_player, daemon=True).start() + Logger.error(f"VLC error: {e}") + finally: + self.root.after_idle(lambda: setattr(self, 'auto_advance_timer', self.root.after(1000, self.next_media))) + threading.Thread(target=run_vlc, daemon=True).start() def _update_video_frame(self, photo): """Update video frame from main thread""" @@ -1095,41 +1041,36 @@ class SettingsWindow: # Configure enhanced custom styles style = ttk.Style() style.theme_use('clam') - # Enhanced dark theme styles style.configure('Dark.TNotebook', - background=self.colors['bg_secondary'], - borderwidth=0, - tabmargins=[2, 5, 2, 0]) - + background=self.colors['bg_secondary'], + borderwidth=0, + tabmargins=[2, 5, 2, 0]) style.configure('Dark.TNotebook.Tab', - padding=[20, 12], - font=('Segoe UI', 11, 'bold'), - background=self.colors['bg_tertiary'], - foreground=self.colors['text_secondary'], - borderwidth=1, - focuscolor='none') - + padding=[20, 12], + font=('Segoe UI', 11, 'bold'), + background=self.colors['bg_tertiary'], + foreground=self.colors['text_secondary'], + borderwidth=1, + focuscolor='none') style.map('Dark.TNotebook.Tab', - background=[('selected', self.colors['accent']), - ('active', self.colors['accent_hover'])], - foreground=[('selected', self.colors['text_primary']), - ('active', self.colors['text_primary'])]) - + background=[('selected', self.colors['accent']), + ('active', self.colors['accent_hover'])], + foreground=[('selected', self.colors['text_primary']), + ('active', self.colors['text_primary'])]) style.configure('Dark.TFrame', background=self.colors['bg_secondary']) style.configure('Dark.TLabel', - background=self.colors['bg_secondary'], - foreground=self.colors['text_primary'], - font=('Segoe UI', 10)) - + background=self.colors['bg_secondary'], + foreground=self.colors['text_primary'], + font=('Segoe UI', 10)) style.configure('Dark.TEntry', - fieldbackground=self.colors['bg_tertiary'], - foreground=self.colors['text_primary'], - bordercolor=self.colors['border'], - lightcolor=self.colors['bg_tertiary'], - darkcolor=self.colors['bg_tertiary'], - font=('Segoe UI', 10), - insertcolor=self.colors['text_primary']) + fieldbackground=self.colors['bg_tertiary'], + foreground=self.colors['text_primary'], + bordercolor=self.colors['border'], + lightcolor=self.colors['bg_tertiary'], + darkcolor=self.colors['bg_tertiary'], + font=('Segoe UI', 10), + insertcolor=self.colors['text_primary']) # Main container frame main_frame = tk.Frame(self.window, bg=self.colors['bg_primary'])