diff --git a/config/youtube.ini b/config/youtube.ini index 4938a11..1e47b50 100644 --- a/config/youtube.ini +++ b/config/youtube.ini @@ -1,10 +1,3 @@ [youtube] # 只写 stream key(推荐方式) -key = qxvb-r47b-r5ju-6ud3-6k7z - -# 如果想推多个频道,直接加更多 key(自动多路推流) -# main = qxvb-r47b-r5ju-6ud3-6k7z -# backup = xxxx-xxxx-xxxx-xxxx-xxxx - -# 如果你想直接写完整 RTMP 地址(兼容旧方式) -# full_url = rtmp://a.rtmp.youtube.com/live2/qxvb-r47b-r5ju-6ud3-6k7z \ No newline at end of file +key = qxvb-r47b-r5ju-6ud3-6k7z \ No newline at end of file diff --git a/dist/douyin_youtube_ffplay.py b/dist/douyin_youtube_ffplay.py new file mode 100644 index 0000000..2930446 --- /dev/null +++ b/dist/douyin_youtube_ffplay.py @@ -0,0 +1,3 @@ +# Pyarmor 9.2.3 (trial), 000000, non-profits, 2026-01-27T08:55:17.463106 +from pyarmor_runtime_000000 import __pyarmor__ +__pyarmor__(__name__, __file__, b'PY000000\x00\x03\n\x00o\r\r\n\x80\x00\x01\x00\x08\x00\x00\x00\x04\x00\x00\x00@\x00\x00\x00\xf7\'\x00\x00\x12\t\x04\x00\xf8\x9c\x18\x90\x88+q\x13\x8f3\x0cs\xd1m\xdf\xee\x00\x00\x00\x00\x00\x00\x00\x00+\xa7\x98YoT\xc8\\\xf5c\x98\xec;f\xa9\xe2Vx\x9c\xae\xda\xbf\x81>\x83\xc7n\x92\xf2PoD\xa3\x05n.\x14^\x9e\x1b5\xf03{\x0f\x86\xc6\xce\xb9\xc8\x9c7\x99\xb4\x847h\xb8U\xec\xba\xd9U\xb6\xd1`j4\xdd^\xec0n\x96C\xae\x1cc\xbfx\x9bE\xc4%t3\x7f#%\x14\xeam&\x93#\xf5m\xa5{\x84Fav\x87av;\xc2\xf2\xd9\xd1\x0eG?\x9a\x8a\x96\xc9$\x91\xbc\xd5\xae\x1e\x1d\xeb\xcb"o\xbbj\xb0W\x0f#Y\xbd\xb9\x1c\xf8\xa1\x12R\xa1\x9c\xbf\x8d"\xa0#C\x1e\xd7J\x96\xe2\xea\x19\xb7\\^\xaag\xecKt\x13\xa4.\r\xb9\x8c\x9f\xa7\xf6\xb5\xdc\xd9\xf0\x1e\xec\xc8\xef\xb7G\x7f\xb9\\rYmI\xcaTt\xa3\xf6\xb9\x0eo5\x83\x16\xec\xb2)\xde\x1b\xad\xeb\x8fu\x053\x93\x06\x89\xf8\xffK2\xe4\xb5\xc3#\xe3\xa7\xa6=)\x9d\xcf{I@\xd06\x8e\xff\xf3\xb1\xe9W\\\xfe\x8b\xba6\xde\x8d\x0b\x9a\xfc+\xc1\xeeb\xbc\xec\xc0,CI\xfc\xbf\x11\x90\x97O\xab\x05\xfe\xc1\xc0\x1c\xd2\xc3\xa9\xc7vAd)\xb4.T\x03!yz]{v\xdfW\x98\xc6\xca\xc7\xd4b\xfd\xf2\x86VB\x80\xc1,\xbd\x11j\x12\xddrv._/g\xa5\x9a\x94g\xfcD\xafk\xf8\xf3\xf9dq\x9b\xd5\x90r\xb6\x0bq}2\xe1\xca\xcf\x9bT\x9ch:\xa4\xa2uL%>\x02\x9a\xae\xb0\x1fgo\x0cZ2\xcf\xd2Y\xa5\xa7\xd4*O\xe3\xef\xae\x01#[\x14YS1,T\xcc\xf6\xc8\xdav\x8f\xb29iS\xab\x98xkVc2\xa7P\xdaE\x1c\xc3\xb8\xb6\xbf\x11=\x16\x1e\r{U\xf85\xad\xe6\xc9j\xf2^\x0bw\x1b\x8e\xa4\xd2\xf73\xa8\xb3\xcc\xbdB\xed\xa6\xd5\x89\xe8\x86w\x90\x1d|\x13$Ua\xda\r\xe2`\x99x\x96l\xc7\x85\x9cR\x80\x81r\x16g^T\xb8\xde\x17\xbbD^\xacy@\xa9\xed\xa7|?\xa9PI\x05\xb06,%\x9e\xce|\xfdX\x13\x1d\xa0.\xe1\xc6rM\xb4\x97\xc8\xc80\x11R\xf2\xdaQ\xe5\xdb\x84\xbcr\x9b\xcbwsI\x8b\xf8\xd5\x95\xec\xc0\xd3\xe8f\xb1:D\x90\x10c\xde\x9f\xc1T\x03\xd9\xb6\xd0\x11\xffB\x1e\xd9\xfc\xe6t>\x97\x88\xf7\x01\xf9\xdas\x16\xf3\xcdEx\xea\x89\xab\xae\x91\x81\x02o\x9a\x06\xa4\xc5\xd3\xfa\x84W\xc8!\xf4\xad_\x02\xea\xd2\xa5\xc7\x97pN\xa1\xd3/#\xc6\xf2q\xa2b\x966v\n-G\xe3,6\xe3\xdc\x82\xaaM\x00\xe8\x8f\xfc\xac\xb8\xa7\x12\xc7xHc\xf7\x1e\x91\x87M6\xc5\xe9H\x85Gv\xf5\x10\xf6\xa2\xd6\xc3\xb37\x9c\xed\xf0\xcd>T\xc1\xa9\xc7\xa0)pQ\x112\x16\xd0\xdb\x8dA\x8f\xa5\x0b\x01C\r\x05\x0e%q\xb2\x02\x82\x10x\xa6\x86[\x18\xe6\x84\x06\xa7i\xcc\xb5\x94\xb4[L!\xb4\x9cwg\xfe\x9d\xef\xad\xbf<:\xea\xa8n\x8f\t]7\xc8\x17\xb5\xd1\x97\xc6\n\xcc9\xb2\x10\xf8\xd7\xd9\xcc\x03\xe5\xf6\xd0`,\xbc\xb6S\xd7\x8cm\xcd\xcd\x95\x18\x81\xdf1R9^z\x1b\xb7\xae\xd7\x8f\x84l\x90\xe1J\x11\xc5\x9d\r\xc9\xf1\xa0\xcd\xe5\x97\xb8X\xa8\x98\xac\xe2xs\xc7)\x15H\x1f\xfc\x0fB\x9b\xd0\x1f\x8d\xde\xe4F/i\xcc\xfa\xb2\x1cV\x9a\t`\x90\xd0e\x9bg)\xbc\x81\x92\x86\x12\xd4}\xc91\r\xa7\x0cz\xe4?c\xabx}\xf8\x93J\x9c\xe3\xa6e\x82d\xbc\x05\x00\xb1G\xf2\x9c\xf2`\xb7Gn\x07\xb4\xea\xb4\xbe\xbd\x9a\x04\xc8\x95[J\xe9\xb6\x06\xeb\x80\xe5j\x8a\xb6N\xc2\xdd\xcb\xcc;\x96\xdf\x80\xad\xfd\xd1\x0f\'\xb5\xccv\xf2\xf0^)\xcce\xc7h\xa5e\xa8\xc5P\xcc\xec.\x12\xe9\x95?\x15e\xa9\xe3\xb4\xdce\x0f8\xc0\x864\x85\x89\x88\x905\xfc\xe7Q"\xbab]\x8d\x9e\xee\xe8r|\x98\x9cQY\xe5\xe0\xbe\x15\xee\x16\x0bE\xd1\x0f\xca\xfb\xfc\x80R\xc3L\xf1?\xf94\xb7\x9e\xfe\xc9+x\xa3\nX\x11VHb\x88\x84\x16}5\xa8\xd6+.\\\x9f\xbeI\xac\x16\xdc-\xb7\xbd\x0c\xdc&\t\x0eX\xfa"\xbe\x02"\x93\xf81\x1f\x83\x16~\xb1\x86\xc4{\t\x07\xb9\n\xa3\xbfJ\nG|\xe4\x0b\x922d\x94\x83s\x02\x80?\xdf6\x14\xc8\xde*\xa8\x13\x8eA\x91\xa1\x9e\xe2\x83`\x92\xdc_|n\x95\xb0ED\xdf6~A\x1dG2z\x16\xbb\t\xf0\x13X<\x93\x99\xca\xd2\xba\xf3\x0e \xf2t\xcb\x08\x17aW\xde\t\xa3\xa7\x03\xe3\xdb ?\xd4\xaaQ\xd0paUG\xb77\xef-d\xb6\x93\x94}}+\xee`k%:\xd3\xeb;\xa4G\x02\x7fL\xe0By\xe8\'\xee\xeeJ\xee\xfb}yC\x06.\x17\x06\xc5Y\xbd\xe5\x99$\xca\xc8a\xdf\x95M\xcf\x0c\xd2\xbc)!\x0f\x86=H{\x9b\xe1\xd2\x90\x88\x04\x87|\x91Rfb-\xd1\xd8\x0fxQMa\x03\xe9C\x85\x82\xac\xb0\x19\xce\xa6e\xaadw\x03\x1co\xfa[\x01gX\xb2\x13J64\x199:N\xe0\xbe\x97\n\x9c^\xfe7\xdd\x08\x90\xb6\x84\x93S\xbcvQ\x8d\x0eG U+\xbc\xeew\xa5\x9c\xb4\x0ebk\xd3u\xf0O\rNp@&\x1cX}\xb2\xe6\xad\x97\x8a\xd0\x81\xe1%\xdb\xa6.\xddn\x8ez\x8b3\xed\xedV\x17\xbf\xa1\xea\xf6M\xe1\xe4\xf2WM]R_\x82kO&U\x99A\x05\xe1\xe4\x8b\x9c\x83\x87\x1ao\x00:\x9d\xba-\x97\x159\x97\x84\x8b\'\n\x1b\xe4\x16\xb58\x9f\xfb\xa8\r\xd3\t\xf8p\x9c\xca\xe3\xf3H\x05\xed\xa3\xbcej\x18\xc8\x8b\xb0\x1d<\x94\xdbC\xfbjB\x91%U\xf0\xb8=qg\xab\xfb\xfe?\x12\x81\x118\x97\xf3^\x9d\xf1\x91\x06\n\xee\x10\x7f-#wj\x8d}\x8e\x89V\xbf\xc3/\xf8\xfb\x93M\xac\x99){\xa1X\x87<\x0c\x85H\x12\xd7\xaf\xfd\xa1C\x11+N\x18\xf2\x1bd^\rz\x02\x9c_\xc0\\\xca@\x19\x10\xca\x19\x9e\xd59MTdU\xd4\xc5\xe0+\x84p.\xf2&\xc3\xa2\xc6]>\xf2f\xb2\xa8\x89e\xf8\x93\xe4\xab\x08\xf3\xb4w>\x1ff\r[\xd7\xdf\x95\xef\x16W\x84\xe6\xd5\xb9\xf3\xba?\xdaN\x91\xd2\x10\xff\x80\n\x17\xa84\x8e\x9f$\xf3[\n\xe3\xde\xd4P\xd3\xae!\xc4\xc0\xaaRQ\xad\x16j\xaf\xa2\xf7\xe1y"\x9a\x94F.\xdc\x8aq\xa3\x00a=\x1d\x0c\xc9Qo\xa0\xa2\xb5&\xc7\xe3v\xfc\xc5\xcf\xae\xcf\xd1\x9c\xb7\xfeM:\xaf\xa4\xae\xad\x7f\xdc4ZN7T8\xbd\x99\xbe\xeda\xf1\x17\xde\xf8k\x83\xf5\xfa\xefV\x7f?\xe9ED\x12\x9e]k\xd1\xdb\xe2!U\xf8E\xfdf-^\xce5z\xfd\r\xc3Ck=\xdf\xab\x05D\xb5`\xc3O\xa0\x05\xd4$\xf4\'\xf5g\x9a\xbe\x17\xf7\x10\n\xdf\x111\xc1\x82\xc8h\xe2\x9e\xed\xd9Gt\xda>\xd6\xb4\xfay\x90\x1f\xebb\xa1F\xa5\x133\x9e\x92VjT<+\xb5\xd1^\xc9\x17\xb5i\x7f\x00B\xce\xb4\xc5\xe9\xf4\xbf__\xe3\xaeg\x12F\xa7\x1e\xd3\xf6\xd0\xa0\xeb\xf3\xdaR \x86\x00j\x82\x0f \xf7\x98\x10a\xcf\x80\xd6\x87\r\x12V\x07\xaa\x0cm\xfb\xe8\xc9\xe1\xe1C!\x19\xff[\xa7?#c\xe9io\xeb"\x96\xc2\x15\xea\xb3\x80\xf9\x8f\x05\xceU\x06j85~\x9e\xf2%\xf3\xb4\xdfH\xbc\x84\x07\xf1\x9d\x88g\x8f\x1bv[\x07~\xcf*U\xad\x14\xb9\x924\nk\xaf\xaaV\x8fU\x16U\x90\xc5A\xdbU\x81!Q\xc8\xb4\n\x0b\xfb\xae\xd2e\xb7\xbb\x07\x0e|\x9b\xaf\xc0H\x91~r\xfbY\x8c\xf2\x0e\x1b\xc0u\\\x7f\xae\xff\xc3*V\xf3\xdf$\xe9f\x1f\x1fx\xb9\xef4\xd8\x00f\x89Z\x8d38\xb1g\xad\xf3\xd7aZ\xa8\x03Y\x19\x9b\x19\x84}U\xcd\xf9a:#\xb4\x85\xee\x88\xd5\x94\xd5\xbeU;m\xfc\xd58\x9f\x17\xd0*r}?\x85\xfe\xf6I\x8ex\x9d4P\x95\xb2e=\xc8\x08+\x07\xf9\xb0\x99\x87\x9c\xf2\xd2M\xa3\xae\x7f\xa2j\x17\x0f\xb6`|\x1f\xbdI\x03\x15K\xdc\xeec\xb6\x8c\xbd\xc8\x029\xd8\xaa8\x84\xc0(\x0c\xd5tx\xbaQ\xec\xbeJ\x7f\xe7\xd7\xa0\x1d\xee\x18^\x80ONb\xea\xf8\xe3]\xbce\xb6o\xa0\x83\t4U\x8b\x89&\x11\xfa\x88\xc8ffR\\\x8e\xaa\xd1\xdf<\xb1\xf3\xe4\xcf\x06\x9d\xac\xfbn\xbdZh\x82}\xaf\xeb\x9aa\xd3\xc2+O\x99:\x0e\xcam\xb2c\xca\x16-\tN\xeb\xd2\x08I\x16R\xc2\x89\xd1\x91\x93\xed]\xfa\xebG\x84F\xdc\rp\xb4\xf8\xadw\xcb\xe5\x8c\xb6e\r\xb9\x9a\x07\x88~\xe4\x8aX8\xc4c\xa6\xb2\x1a\x9bT\xa7(\xa1|\xd7\xa4\x0c\xcaA8\xd2s\xf3\x81C \xfa\xcc\x17\xa7\xee\xf0\xd1&\xa5\xfc^U\x97w\x95\xc2\x12|\xfd\x84\xa8\xc6\x81\xb1\x06\x0b\x82\x06\t\n\xd9L \xfcWP\x9c\xe2)\x93\xbd\xee\xd4\xd2\xff\x06$\xdc\x95\xcb\x19G\x80\x11\x19\x81u\xf4e\xb8\xe7wW\x90\x7f\x01#c%\'R\x9b\x0f\xa6Y0\x07!\x0bE\x05;r\x7f\xfd$\xcbah\x92\xdfpPA*\xd3\x04\x0eu:\x1d\x06\x01\xdf\xe2d\x1c*&En\xc9\x19\xae\xbe"M\xa3y\x16O6\x8e\x16\xcb+\x84\x93\xf1\xb0\x8d\x03\x9a\x9b\xa9\x9d"\x80\xafj\xb4\x80\x91\xa5bX3(\xe2&5\xa1}\x8f\xf0\x9b\xb02\x17\x1aZ\x18\xfars\xf92>\xcd\xd2D\xac/\x8f\xb9\'\xb3\xa8\x0e\xe5T9\x03V\xd6\xea\n_\x01\':\xa3\xb5d@+9.\x94j\xee\xa1\xa4\x92\xdd}g\xffC\xd5MO\x9a\xaf\x1f\x19Gl\xab\xd7w\xce\xa8\xd6\t\xf0\xe1\xe6\xbd\xb4\x876\x98\xb9}\x90\x83Z\x08\xc0\xcf\x8dC\xb9\x82\xa8\xf6&_E\x1bP\xaaj\t\xe3\xb4nN\xe5DeJ\xd4\xccN_HQ\xad\x04\xdb\x02\x04UQ ]\x8f\x1f"s\x9a^\x94\xa6\xc0:\xd6\xe1\x1c,\xeb(\xda\xe6\xfd\xbc\xa48)\x8b\x80\x08\x97\xc8wKYcB7\xf9\xf3\xa5r0Nkv\xd7\xab\xc9_\xd2_\xeb9}\xaf\xfa\xb2+\xf8\x04;\x93\xcc\xea\x88\xa0MM\x8f\x90\x81G\xa1\xe7M\xa9(\x0e\x1fD\x1a`*\xe7Fc\xfenO=3\xad\x91<\x12\xa9\xfft\xd8}\xa1\x04\xc3K4}\xbf\xa4\x9eaF\x9eA]+l\x8d\xc7\xc0\xd3\xc9\xbb\xd4L\xd7\xd4\xbc[]6\xaa\xed\x9a\x13\xbd\xe7\xce\xbc\xfb?\xedk\xfb1#\xc7\x93N\xb6\xa7\x1c\x01\x0e\xfa\xea\xc4%Wxi\xf4\xc0L=!qi\xc5\xca\xbau\xbf\x89&`EyQ\xdb\x94\xbc^\xe7\x81\xe0Zl*\xad\xeb/\xbd`?\xe6sK\x01\xb8\x9f\x1c\x0f,\xd6\r\x14\xb5TO8F\x1d\x15\xb9FWu\x1e\xcft\xef\xe4\xa7\xa6n;\xd3\xbe\xbf{\xd3.\xd7\xf0\xffa2\xacj\x93`:\x11\x02\xd1C\xf0\xf5J\xa6\xe4\xf1\xf0Zb\x9bG\xc5\xab\x99\x1e$"\x90\x10\xa0 \xfe\x9c5C\xc7\xf7\xd8gZ\xbdy\xb4ZM7\xa2\xff\x9a\x1d\x1a\xcc\x95\xbe\xa8\xab\x0e\xefP\x9c>\xf6K\xa3\x00BQN\xd9I\x04w\xab\x8d\xa9j\x93y\x10\xbb\xc7\xaf%\xde\xb3\xb0]~\x99D\xfb\xc2\x0fk\xe6,E\x14BJ*\xbd\x9cT\x8b\x97\xad\xa8u\xb8\xf3,\xb4\xb7\x881U{\x01A\xfes"B\xdc4M.pf\x04\xcc\xb6\x8a\t\xc3J\nK1\xba\xf2~S/\x8e\x0c\x06\xa1\xd0\x91\xd6\x0e\x8b\x83\x07kR\xf1$JA\n\x18\xee\xd8P5d:\x93Vs\xadxk\xd5\x8b@!\x15\x073\xdd&\xa8\x13\r!\x87\x145\xafKo#\xfe\xcb@\xe2f\xa1\x98\xc5\xca\xecP\xf4\xe8\xf3\xe8\x94\xb6.3z3\xceN!\x18\x98\xeb\x11\r\xe8\xa9\xc9\xfaG\xbb;~\xd9\xef=j\x1d*\x80\rv1\n\xc8\xb9\x86s9\xb4\xd4c\xdaC\xfbB:\xfd\xddjs\'\x14\xe2q\x87\x08\x11\xd9\xc8A\xd4DJ\x8391\xb5\xb8\xf1{w\xb3\xef\xc3\xf9XMA\xae<\xbe\x13\xad\x96v\x1dp\xf52\n0\x9a\\\x9e\xc4h\xbc\xdb*n|\x04F\'\xec$\xad\xfc[\x14\x9f\xfa:\x83!v\xc1\xd7\xc2\xec\x0bQgwZP\xdd\x06\xca\x99T\x9d,6\x83_"\xd38\x96\xafr\x91\xf7\xe2\xc5\xb9\x947\x15>\x83e1?\xf8\xaa\xa6\xd6\x7f+\r\x08\x92\x10\xd2\xf4\xb4\xb4\xce\x10\xa5\xe1}\x8a|\xc7\x05\\\x04\xa3e\x15\xb1\x9d\xf4-hL\xc7\xe4\xdf\xa3\xd8\xda`m{<\x85^\x11\xfe\xaeSgfb\x0b\xffU~\x04\xc2\x9e\t\xd1-\xbe\xe6\xac\x17\xad~I\xa4\xd8\xb9\x06q \xc5\xea\n|t\xbd\xd9\xaaL>\xc4@A\t$\xfd:z:g\x8d\x18\x00\xb7\xfde\x18\x92D\xaf\x86\xf6\xd4\x7f\xb7\x15\xf3cT\x97\x1a\xae\x8a\x03\x1d7\x88r\x903\x14S\xc0\xbd\x83\xcd\xa35\x9e\x94{c\xfca\xcd\xac\xd4\xb43\xa2\xaa\xe0E<#\xc34G\x18<\xc7p\xeb\x95$\x82S\xc5>\x08\xac\x1f\xbb\x0b\x7f+JF\x83"\xbfA\x1d\xe1\x8b\x80=;L\xc3\x1b(\x0b\x914\xf4\xfa\x93}\xd8`\xab\x0b\x14C\xb6<\x95P\xcd\xee\x94\x0e\xc4\xd7:\x19\x18c\xba9y]\x07\xc8\xab\x06-y0\xd1\x8fr)#$\xa3)}\xd9\x98v\xef@\xf6\x85\r\xe2\x0b`\xfd\xeblA \xbc\xb1\xa0]\xc8\x9b\xf4\x10[h\x1d\xc5]}\xa62\r\x11\xe9\xe2t!\x97f\xa9V\x1aF\xb7\xe1\xdeN\xb8N\xd9\xf0\x1eNI\x88Cm\\\xbd)v!$\xf0\xcbh\xcb"YR~\xf6NzM\xa9\x91\x8f\x99\x8b\xbe\x05M\xe4\x13\xf4u\xf0\xcb\x13M14\xc1\xd1\xe5\x11\xa2\xb5\xc9#\xbek\x9c\xfb)\xa0\x86\xd7M\xe1\xd4kY\xa72\xbec\xa7\x12\x8f\xc1\\\xb3W\x83q\x9c\xaeex\xf2\x9d\x05\x7f!\xa7+\xa7\xb9\x1a\xe5ZA\x1a\xcdI?\xe2y@,-\xd1\xa7\x1d\xbfD\xad\x9a\xd3]U\n\x80\x9e-\xfa\x1eg\x05\xc2\x8f\x98\xfcKU\xfa\xe0l\xcb\xfb(\x05\x89M\xe4f\xe6\xd00\xec\x06(\xa8\x1c\x1cU\x16\xaaG\xe6\xec\x9f\xf7\xb0\x9f\x0f4x\xb1\xc9\xdf\x0c\xf3&\xd8\x03\\*\xb7m!\x96\t\xc9\x85\x0c\x8b\x0f\x9a\x89\x13\xda\x014u}(\xa7\xe5i\xb6N\x0b.\x02\xbb\x8c\x03D\xf6\xdaR\xae\x9bo\x83\xb5\xec\xaaa$>g\x1c\xf97D\x9f\n\x1c\x00\xbd\xf2\xbfa\xa1V\xa6\xb5\xcd\xdeycz"O\xe40\x9afC/\xf9\x05u\x94\xf9\x1c\xed\x15\xb3\x06)\x9a\xfb\xd1B.9\x07{\xc7\xb9H\'\x8fu\xd3E\xfb\x97AFs\x86H\xc0u5\n]DA)\xb0g\xf5\x86= \x06\x1f\xbb\x1c\xe8z\x92\xc4\x0f`\x0e\x84\x16\xfa9\xcb\x9cnOJT\x0e\xa7\xb5dg\xff1\xc8\x15\xdf\xde+\r\xd5\x9f\xb1\x06\x8cf\xe8\xb2,j\x06\xd2D\x0cV\x1a$D\xc2\xec\xe0\xa4H\xab\xef\xd4\xd0n\xd4\xfdO\xda\xa8\x86Y\x05B\xbb\xf1|\xa2C\x9a\x87\x02\x8b9\x03\xc68=\x8d\xb4\t\xd7\x00#W\xe2)\x88\x93yI\x06\xb6\x0fn!\xd4\x96\xfaK\xf2\x0c\xcc\xa1\xdc\x1c\xdfK\xaeX\xdfKEYa\xbd\x99\x84\\;T\xd3\xa4\x89\x96t\x85\xd3\xa8\x95X\xff\xcb?\x8b\xfe\xa5\xb4\xcca6\\Qn\xf1iz\x17\x0f]-9\xfb9\xa6\xb9!x\x12\x0b+\x9e\xdd\x16z|G\xba\xb8\x86L\xfe\x99\xc5Kx\x7f\xe2]\x89\xa4\xc89/\xa3\xfb\xb3&\xd1\x89\xc66O\xbd\xe3\xa2~\xe3\x1b\xfd\x01m\x07%o\xa5\x03\\\xbf\xfa\xdf\xaa\t\x9a\xf3\x00\x978\t`-\xa0m\x9a\xecT\xbb?x\xc2\xb0E\x01\x99\x04\x04\x82\xea\x06\xe2{\xbb\x06\xff\xb0\xbc\xa7L\xb6O[I:\xc9q]\xa3\x06\xab\xe0P\xcf\xcd\x10c\x07\xa8\xcd\xdc\xaf\xe7A\xdb\xd5L\x082\x06\x9a\xcc\t\xf6\x8aT\x8f\xc4\xee\xe0x\xe8\xbd\xc3\x01\x0e\x18h\n\xe9\xa5P\xc1^\xfa\xda\x8f\xa3\xa8\xeck\x9d\xda\xb5\xfeS\xb5\xf0\x90o\xbe.\x0e\xb1\xf0\xa3\x08\xc0\xe7\x90\x14\xba\n\x8d\xbai\xb0\x8c67\xc2F\x1e&\x10E\xe7\xa5kF\xfa\x83\x82\x17}\xf2\x0ep1f\xe3\xb8\xdbm\xae+\x89\x87\x19\xc0\x16\x11\x00\x89k\n?i\x08\x11l\x9f\x0ep\xec\x809\xef|2e\xca\xb2m\xd7\x1e\xf7\x82Z>ya@~\x0c\xef|\x8dp\xd7x\xb5\xbc\x15\x9e\x8a\xbaSf\x9b\x86\x88ELfF\xda\xe68\x90\xbd\xb6\xfe\xd02\x18\xa6\xa4\\\xd5C\xce\xb1\x81^+\xad\xba\xaa\xe4\xae\x94\x83\xc7\x93\x80\xc6mdv\xc7\xd8\xf9\x19\x7fab\xe6\xeenm\x8d\x0e\xdf\x15\xe1\xbe(\x96\xcb=v\x04\xb1\xc3\x90J\xbc\xab@E1\xa8a\x87K11%{R\xb6\xab\xe8,`\xd3m\x11\\ha\xd7zNv\x9c\x18~K\x1f\xe5e\xcd\x11}\xe7@\xfc\xd1\xde\x9e\xe0\xa4oQ\x1d^\xe3\xdf\xd5Y\x0b\xc7\xc0y`?oZ\xd7{\x00CC\x16\x19H:\xfd\xfd\x81}\xcf\x9a\x0fcv\xe0\x9b\xf0\xcbH7\xd8\xd5~\x06\xbdo\xe9t\x97\xf4\x7f\xed\xe6*N6\xaf_k\x86\x7f\xf8\xe1\xf9\x1bw\xd5W\x9f\xaf\xbcz\xbf\xdd\xe1}\x8a\x18m\x92\xda\xb3"\xac\xd2\xcc\xcf\x8d\x9f\xa9T\xbc\xee\x9e\xd6(\xbb\xf3\xcf\r\xf7\x80\x13e\x1d\xf1Q\x02B\xab\xd4\xb1\x17\xa6\x91R\x9b\xee47(\xb8\x19\xd3]E$4\xc8\x9d2\xa0@\x8c\x98\xd0\x14p\xb0\xbb_\xc5\xdc"\xb6\x86\x9f\xb9\xd2\x97\\K\xd7v\xf4\x90t\xcf\x8b(\x84\xb8\xd0\xb2\x03\xff\xd2~\x85\xa6\x92( \x8d\x9d\xff\xff\x01Md\xe8\x1cng\xa9\xac2\x92\'\xd4H\xf2\xf9\xd1h\xffd)<\xf1\xdb\x1f\r\x1f\xa5\xaa\xb5\xa0(\xd3\'\xb4\x9bH"\x8c\xe0Z}\x9e\x83\xea\xff\x06\xf3\x96\x956+\xf9(V\xfb(x\xe7~\xc2\xfd\xfd\xa8c\xefXX\x99\xd4\x88\x0c`/T4\xb9\x1b\x98\t\xc5\xc6Au\xe8Uq\xa1N\xe00\xf2\xf7E,\xf7\xc9\x8d\x12\xb8\x8d,\xa4\x02\';\xe9?\xd7k\xc4\x06\x07\x8e\x1b@\xbd\xd88\x0fW\xcb-\xfe\xdf\x94(C\xec\xd3\x05\xc8\xc9`\xb7\x834d\xbb\xc8vDu\xcb\xe3\n\x13\xfd\xba8\x85\xe7\x12no\x95\x15\xaaz\xf8\x15\x17\xce\x16c\x89\xfc\x19\xc4\x90m\xb35\x19`\xe4;\xc3L\x85\xb6\xefQ\x8c\xcfv|`frq\x9c\x05\xf2\xec\xa4\x12YE>b\x8dcW\xe1!\xfeG\xfb\x12\x96lF\xf8\x95\x89\xd8\x8cP\x0e\xb5YyY\xa8\xbf\xc6\x9d\xee\xe3\xc4\xc8\xad\xe9\x00K\xe8{8\xd5\x8c\x03L\xee\rV\x15\xc8\x83x?\xee\xb6g\xad\xa9\x95\x0fz\xf1\xba\xe4\xb1Pq1H\'1`\xb4\xdf\xe0p\xbbZ\x06]\xa5\r\x9e\x07\xd2~\xbchw\xf2\x92\xc7\x8cd\xd0\x0eY\x02\xa7\x16|\x15\xc5)6\xd6\xc8\x1d;\n8)`\xa7\xe2\xb60\xef^\x94B\xc6\x92\xd7YB8p\x94\xe6\xe5\x16\xbf6\x99\xf0\x8d\xe3J\xe0\xfe\x05\xd6\x85\xef\x93\xe48[Z!\x8c\x15\xb3\x17{G\x0e\xd2S\x88\xffN\xb2\x11\xd8\xcf\xd7\xf54\xbc\xc0\xc7,\x18^(a\xbb\xa0\xad\xec\xaa\x17\x17N\xfc\x9eY\xb7\x05\xeb\xf5\xae\xa2\xbb\xadBa<\xfcQz\x92\x00s\xceFJF\xe6\xe1\x8a\xc0\x01\xd8d\xe3X\xef\xda\xbd\xd0\x88\x0fW\xeb\x92\xdaP\xa2\x87r\x12 \xf84\x02\xc0\xb0\x1d\x01fG\x9fH\xfc\x1cI\x1b\x06\x19|\xac\x16\xc5\x9d$\x9b:\xe8o\'\x00\x01s\x9e\x97\xfe5\xa0q\xc7\xa9)r(\x832\xc4h\x83&\x9ds\xd2&\x1d/\x8c \xe06\xe2\x9c\xba\x93\xd2c5y^I@\xab\xf8e\xc9>\xe2j=\xe7x\x07\x85R}\xf2-@`,)\x93E\xf4)\xf7\xfaR\xa3\xc3KFj\xfc\xf0\xdf_\xaf\xc9\xab\xf2$Sz\x8d\x1d\xc7\xbf\xdc!\xc10M\xf4\x8f\x17\xabX\x8d\xe6\xd4\xf0\xe5\x0f\x11\xe7Z\x9c\x81P\xd5\x8dwLe\xe3\xbf\x17^\x0c\xd8\xe9@$\x97\xb9m\xc1\xce\x99\x1a1\x1eN+\x0b\x90\x00\xe2}d{\x1cDg\xd4\xcf\xe0\xb7\xe7Mp\xba\xbb\x8c\'\xc2\xf1}Y\xd7T\x10\x9cF\xd0\x97i1h6\xd3}.6\x97\x9b"\x81\xce\xcb\xbf\x9cF\x80\xd7\x1cMh\xf2-T\xcc<\x98\xd2;\xb4\x86\xa2O\x81L\x8c+US\xf8\xa1?\x12\xaaX\r\xfb;R\xfb\xa5O\x7f\x15\xa4\xe8&~T\xc0r\xbc\xaf\xd8\xd8"\xc8\x17\x85x\xe9\x86\xaf\xf0\xce\xff\x10\xa9\xeczG\x90\t\xec]\xc0L\xbd\xd5\ne:\xcc\xf8\x7f\x93p[\x16\xdby\x930Y\x95 \x1eKV]\xcd\xdd\xcb\\\xdd\x82\xae\xdd\xf5\xf2\x80Z\xab\xf4MK7\xf8@l\x86E\xb6TW\xe8K><\xc49\x13\x8e.\rE\x1bG\x04\x12O\\\xd5\xd4sx\x86y3\x0e\xbaC\x8c\x16_~\x88\xaf\x85\x8c}\xebj\xa3?\xb3\x17\x7f{%\x84y\x8a\x13\x16\x85,\xb0\xdb\xcb\xac\r\x84j\n\xb7h\xc3e\xb7\xa8\xd3\xcc\xf9\x9eh\xe8\xb1I\x90\x82F \x14\xf6\x84\x15CD\xe3\xab\xdc-6\xee\x0e\xc1Eqj\xb3\xc9\x15\x99\xaa_\xeb\xe8O2\xe4\xee\x1e+\xc1\x82B\x9d\xb1\xd9;\xa0\x03\xb1`\x16*35\x18\xf4\\p\x8a\xf2\xdf\x014\x0c\xe0tCi\xd7\x7f\x8c\x1f\x1a\x17\xae\xe7\xd6\xdc\xf57\xbd\xd6`rZ\xb4\x88\xe7\xbb\xa3\x82\x9bPg\x01T`B],@\xf3\xc7\x1a\xaf\x04\xf0\x91B\xa04\xb7\x8a\xbb\x01\x0c\x00\x9b,\xa9\xe4K\x8b\x9c\xf4\xd5J\xb5C\xbf\xa9\xd6\x95\xc3\xb9D\xe9\xc3\xe60q\xac5T\x836\xf4_\xee\x7f\xe4z\x91\xc0N\x9d\tD\x84\xef\x81\x0e\xc0o\xb5\xc5\xae\xc2Q\x9dD\xca\x8e$\n{\t\r\x05\x16\x0c\xdf+\xa3m\xdf\xe3\xf6\x01x\xd5\xa9\x12t\x82i"\r.M\x0eM\x8f\xd5\xd9c\x10 \xfcK\xaaO\x7fW\x1d\x80\x9bH,|\xb9\xda\xdcYN\xb1\xacW5C:\x01\x002@\xd1\x1e\xa0M\xc3\x12\x1c>N\x10Fs0B\x8f4\x1d\x07\x9bG.\xe7kj\xbd\xe2{\xd9\x00x\xe1Z\xc4\xac5\xc4HS\xf6\xefjVX9B\x16S\x0c\xbdn\xb7\x99\x9d, \x84J\xdcm\x8cf\xf1&85l\x8f\x99\x01\xe8\x12\xc2\x0b\xd1\x94!\x89\xb2\xac\x00\x06\xd2\xab\xf94\xf2\xdc\x16\x10\xa1U!\x96\\&#\xb4\xaa\xf6\xc8\x0b\x96\xb6y\xca{\xa0\x15\xd3\xdbb\x93\xbf\xfci\xdd\xb4oq\xeat4?\xb4\xad.\xbe%7j\xe5\xadR{\xc6C\x8bS\x86Z\xaa,\'U\x93\x9co\x06\xe6B_\xac\xd5\xdb\x0e\x17+\xa7\xcb\xcb 9\xb2\xfb\xb1\r\xe3=\xc9\xcb\x7f}\xe4\xe09\x96\xe5\x04UV-g\xd7\x8e\x1d\x8c\\\x1d\xb9\t\x9ap\x19\x0e\xc7\xc5\x0b\xa6\xf2\xa3\xd2gLH\x98\x80\xd9w\x81\xa4\xfc>\x8d\x98\xbenz\xd5\xde\x98\xf6\xe9\x83?a\xbd\xf5b\xb8r\xe2\xdf\xff!\x85\xbe>}}\xf7\x9fQ\xe1\nFXoE\xf8\x1c\x15\xfd\xcay\xc8\xf54\xad\xe8u\xb3>\xa1N\xda\x9a\r\x8c\x9eU\x9b\xbf\xe9Yw\x19\xd3+c\x81\x07\x1fO\xc0\x81\xc0\xd2\x03\xe1-X\xaeq\xd7\xe7]\xb1\x98\x0b\'6\xd2\x93\x17\x83Ix\xb5+\xca\xcb\x04\x03\x8f\xf3\xb5Mz\xa6\xd4\x0c\x9dz\xe4\'\x17\xcfm\x8e#\xcf.<%K6_\xbb1\x16mI3\xf4\x9f\xb5\xfaK_\xf8W\xa3\xe4P\xc7"zH\xa7\xa0.\x14\x8c\x0b\xea\xbarwxG\xe1q\x03\x91\x83Z\x0ezO\xe2\xeb\xcb9b\xc0\xfe\x8a\x8a\xa0]\r\xe8\xef\x93\x1b\x06M\x00L\xd9\xd4\xab\xf4.\x1f\x16\xfd\xa6\x0f,\x19\x00K\x1a\'\xc1\x8a\'\xe1\xb5\xb9\x85\x8926\xfd9\x8f0\xf3P\xb7\x8e\x7fX+\xa6\x8b\x85\x96\x17\xe6*\xb3\xd5"\\\x81$\x8e\x11\x86\x82K&\x1b\x16\xf8{3/r\x84\xc6\x00K\xb6rZ\x13\x9b\xd0A\xca_\x96\xf2o\xd8C\x88\xde|\xb1>\xe2\xcb+\xe0\x98\xc3\x00\xa5kV\xc8\xefdh0\x01\xb5\x9a\xb5\x95\xb7\xac@\xe1^s\x19\xa9\xe5\xdf\x117\n5\xc2w\xcdq\x18\x02\x81\xbd]r\xaa>\x87\x9bJ\xa5\xe6\xa3;\xf4!\xd1\xd0\xc7\xb9\xa6\x86/\x9a\x19\x12\xcf\xff\x98\xc8\xa1$\xda\xa6\x95zk\xa4\xfa\xc4y\xa7"\x80CH\xb5e\xcf4\xa8.U\xb5M\xed\x1f9\xe0\x97w\x15\xb3\xceEJQ\'\xe0n\x0f\xdf\x89\xa7\xb5\xa2=\xa8\x83\x0b\xd9\xcd\x84J\xb1SN\xe5"\x84:\xc8/\x8b\xa4;\xddr\x84\xc2\xa6\xc5W\xf7\xa6,\x98:\xc0Z\x04\x98`b\xcd\x0b\xa5Y\x13\x17\xfc#`\x06\x87:\x08m\xba\xf1~\x86.O`\x01Rd\x06\xa9\xa0\xb4\xca\xee-\xd38E\x9f\x96\x8c\xf3\xeb-\x14o\x88\xfc\x83Jgi\x7f\xe8\xe1$ \xc3\x12\x1b\x9dO\x89\xfa\x19w[R\xf9]\xf4\xf7^\x96\xb2\x97 7b\xb2\xdf\x9a+\xear\xa4\x06Mq\x9bq\x80A\x1eXz\xc6\xff\x1b\xfc\xbc\n\x07\x1a\x10Z\xd4\x99\x8c\xf9\xaf\x8e\x97\x0f|\xd9\xe2r+\xff\xfc\x1a\xff\xf7\xf8\xd0\r\xe6\xa9\xdd\x9d\xc1p\x8a_vuw~)#\x9b\xc2x\xe2sJd$\'\x8co*\xc3jF\xe2\xd2\x88\xa7n\xff\xe6v\xb4LuJB\xf8\t\xc7\xa5\xe1\x88`\xdf\xff\x13\xfaZ\x8d\x8d\xd7\x969\r\x9a\xfcX\xe6X\xd1Y\xaf\x08\xe7)\x11l\x81\xa1\xa8b++\xd5k\xdb\xd5e\xd7>\xa4\xe2\xa2!\xfaF\x1a\xdd?\x9f4\r\xe6\xb5\x91\x9e`\xcb\xa0\x11DX\x8c \x80\xb1\x90t\xc4\xd3\xc5\x02c\xbe\xa9\x12@\'d\xac\x04J\xe1\xd6\xf1\x8d\xf6\x0b\xb6\xa4\xd3?\xd8\x94\x19\x07\xff\xdc\x02x\xea\x84I(U\xf7\xc8}^\xc8\x9f\xee\x99\xf3N\x0flTpz\x80t\xf0c\t\xfb+^v\x8d\xaa2\xd86\xda\xd5{\xba\xa6\x06\x9d\x9fW\xeeL\xb9\xb5\xc7"3_\xe6\xd9\x80\x1a\xc9\xadD\xaa\xfa\x19?7\xa6rWq\x1c\xb7N\x19\xbb\xce\r\x08\xe3\xf9h8[\x04\r\xe4=\xe7\xad\xc8\x0ewM\x9c\xff\x0bA\xb0\xc1\xf9\xc7m7\xd8\x92\xc8m\x85[\xbe\x965\x9e\x12f\xd3k\x04A\x03\xe8\xa9\xcf\x8b\xd4\xf7\xb8I9:\xef\\\xddU\x0b\xfa[\xeb6\xb9&s\xe3\xf0\x03\x08\xe8_\xfdz\xa2c\xd4j_\xc0^\xd91\x12y\x89\xeb\xb3p\x93\xc6\t0\x0e5\x01M\xd6\xc3\x801\xde\xe0\x17V\n\xfeo\t\xbc\t.c\xf2G\x82\xb6g\xbczw\xf7\x88\x85J\xceR\xc7xYD\x0e\r\xb9\x97?\x94\xc6Gh\xb3f(6\r\x17\xb6I\xf5\xc8&|\x9ay\x99\xa87\x9b\x90e;\xba\xa5x\xc7\xd0\x84\x84\xfb\x16\x17\'-\\\x9fP\x08K@\x02(\xf6Q\x8d\xb0\x94\xde\xbc \xa1\xaa\x97\x17\xc9p\xb6\xa9\x8b\xde{68\x08\xa1\xd3m\xe6\x99`\xdb\xd4\xa1\x00\xd0\x81\x88O\x1d\xb6\x14\x12\x8c5_\xc4\xe4Z\x8d\xfd\xca\xc8\xd4B \xbd#-)9pcq\x10\xd7\x85+\x10\xbf(\xe3\x15A# Y\xd0\x7f\xae\x94\xf9\xadW\xb2\x1f\x07\x15\xa2\x88\xcfr\x84\xf7\x8c\xa9\'\xf4\xd3\xc8\xea\xe0\x82b\xc1\xa9\xf1;5\x96\x86\x84\x94L\xa3\xdb\xaa\xcbN\xb9\x05W\xceRu\xd3\xb4\x08\x9f\xaf\xc6\x1a\xc4\xe7\xad\x14\x1d\t\xc7\x19q5\x90\t\x86\\#v\x92\x19\xac;\xe2]\x1bv\x0f!\xfb\x1f\xb7l}\x99\'`\xc0\xa3Z\x10\xef+L\x89\xd6\x00\x17L\xe6\x80\xf6\x8e\xcb\xdb\xc0\x9b\x93\xcb\x11\xee\xfa\xcb\x9f\xb6\x04B\x1a\xdb\x065P\x7f17\xfd\x95\xb8$\'_h3\xe0\x9b\xc4\xd9A\xfd\xddHjk>35\xe5\x97\xb4\xf9\xbc\xde\xdc\xcdI\x8dn\xda7\x1b~o\xd5\xf7\xd2\x10\xf6\xd9\xbe\x06\x10\xf3\xf4\x11,\x07\xd0I\xba>\x97\xcafNf\xb6_\x1e\x8a\xdf\x90\xfbU\x97\x9e\xc4W:\xa2\xa8G\x87C\xc7\xd6\xd2\x8d\xafi\x9d\xa2\xe4\x08\xea\x10\x8f\xe9\xa3\xbe\xdf\xea\xa4@/\x87\x14\xc8HI\xa8V\xd7\x92B\x0b\xd5\xe4&\x83\x9f\x12F\\\xec\xb5\x0f\x16\x9aEdw\x9bkl\x03\x87\x13\xfd.]i\x0e\xcc"S\xbe\xdeS\x010w=!J\xbd\xef\x82\xbe8\xe0a\r(]\x93]I\x91\xaf\xbb\xb8\xdeh\x03\xfb\xa2\xbc\x03\x83>\xc2`\t\xdc\x13\xc0\x06\x1dwr\x10\x17\xbbu`N\x11\xe3\x0e\xea3\xcfp\xa6\xce\xac\xa1\xee-\x80\x8c3s\x08\x9c\xe3E]=\x06m\xb5\xd8\x98\xa5:\x0f\xc7a\xec\x03\x84\xec\x13\xba\xa8\x8c:Oh[\rA\xe7%\xa4\x85\xbb\x1fM\xac\xdd\xd3\xef@\xcd\xff\x05\xfb\xde\xebN\xa02H}d\x81\xe3\\\x04\xd6\x81p\xf9\x14o\x8eP\xa1\x9fX\xa6aAD|9\x01\xa0(\x96\xd3\xf2p\xd1\xae\x8b\x19\xd0\xd0\x8a\xa4\xafG\xef\x16\xee\x93\xf2+L\xcc\x90\x07\x81\x040\xf5\'\x98S\x1a\xf4\x08\xe9\xdb\xc7D\xe0DV\xf4\xb4\x99\x8d)\x99\xed-\xb3\xf8}vsiW1\x05\xae\xcdt\x89\xf6\xfc\xb0\x14\x18\xe3R\x94\xb9\x1c\x1b\xea\xcb?TRX\r\x8a\xbc:\xe0aY\x1f\xfaK\x9d#\xbc\x80S5\x87~\xea\xeaFP\xde\x92}\x10\xc8\xff\x8e\xc9\xb9J<+\xee\xf5\xf81#\xcc\xf4\xe7\xa3\x9e\xf2\xc4N\xdd\x9f\x84\x02\x13\x12\x15\x02=.\x8f\xd1O\xd0\xb9\xfb\x98\xdd\\\xee\x8f\xd4-mY\xf3\xac\xae\xab^1[\xe4\xd9\x15*]+8\xd6C\xf1\xf0\x9a\x85\xef\xd5P\xebf\x89\x18\')\xdc,\xb4\xcd\xa1o]97\xd2s;^O\xec\x98\xa6\x1c/\xac\x94\xcb\xf7\xd0\xc6\xc6\xad\xa7z\'\x9a\x8fq\xad\x1a/\xfdt@T!\xb3m\xc3\x1b\x81\xbc\x81\x96\xda\x11e\xa7\'\xab\xee5\x91!\x1a\xdb\x14P\x9b\x1d\x1e\xd0g\xc6\xae\x00\x0f\x8b\xa18t\x13p\xfb\n*\x96Q\xcc\xd4\xae,\xb1\xf2b\x18\xb2#\xe5\xe2\x006\xc3\xd6\xa9kw\x10\xaa\x81&\x10@z9\xcel\xba\xab\x8fU\xf2#\x19n5\n\xcc\xa3\t\x0e\x08\x84\xd4\xd8\x86\xb7"&QB\xce\x06f\x7f!\xf3z\xaa\xf5\xc0\x12\xdb5\xc0?\x02\xd9$)\x84\xf4pg&n\xbfL\xd9\x82\x1fh\x8b\x12#\xf2\xcdJ)\x12\x12\xac"Q\x1e7\x90XI\xad\xefm\xbaA\xdao}\xeb\xb8\xa1*@\xc5g\xd2\xd5\xe0\xe8\xc5t\x16r\x8b\xa1\x83J\x92\xc6MJ\xb9\x1e\xdc\xaa\xeb\x89\x92P0a\xb9\xc7\xf0O\x1c*\xc0\x12\xe9\xe7\x02=\x91\xa5`(\xe2\xa8\xaf\xbb\xb5\xff@\x90\x16J\xf8\x1c\x10\xba\x86\x07\x80a\xb4v\xa3\xc2\x03\x81\xf67\r\x0c"\x16T\x939z\xd6\t+\xc6\xcc\xd44\xf2f\x13\xf2\xde\xadD\xbf\x9eD\x82\x07E\xf2\xd7\xea\xf0\x00S\xfcp\x1bb\x9a3\xe5 \xd89\xd6\xefU\xf5\x0c\x14\xf8AW\xb7Gj3\xe7\x07C\x8d\xd7_\xa0\x933\x11\xbc\xf7\xc7\xc3#\x12b\x7f\x05$JYZbh\xa8\xcdp\xf1,6\xc2\xb8k\x18\xec\x9e\x80\xc9\x9d\x06\xa4\x8et\xc7\xb1\xc9V?D\x87\xfas@x\x87\x84}\x1f&H\xbcUp-S\r\x9a\x8e\x13Y{\x0b\xd9\xd4\xaa\xcb\xcc\x1dR\xd3\xc6!%\xf3y8\xc0I(\xad\xf2qr\xae\xc8H\x90|\xd0\xcep`ec\x9c.\xf8\xe2\xa3\x8d]_V\x0e\'\xc1l(X\t!\x89\xf0\xeb\xb2*7\xc2\x1dy\xe1\x8b\x8a\xcb\xd8\xfb\x8f\xf4\x05E]\x7f\x98\x96\xe1a\xd7T\x84\xd3\x16l\xa2\xbf\xb4\xa4\x99\xe8Qw\x8c!g\x93\xeb#\xd2\xfaT\x19\x9a\xa7\xa5\x96\xca\xdd\xbc\xed\x00\x00\x97\xd5\xe8".\xfd\xdd\xc6\xff5\x82\x8e5~\xab\xcf\x82*\xa1\x92v/\xc4~\x86+\xec\xf3\xbc{\x05\x91\x18]f2\xc7<\xcc\x18e') diff --git a/dist/pyarmor_runtime_000000/__init__.py b/dist/pyarmor_runtime_000000/__init__.py index 9540c4a..a36384f 100644 --- a/dist/pyarmor_runtime_000000/__init__.py +++ b/dist/pyarmor_runtime_000000/__init__.py @@ -1,2 +1,2 @@ -# Pyarmor 9.2.3 (trial), 000000, 2026-01-24T06:52:53.934396 +# Pyarmor 9.2.3 (trial), 000000, 2026-01-27T08:55:17.418182 from .pyarmor_runtime import __pyarmor__ diff --git a/index.html b/index.html index 05f1705..878eb8d 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,6 @@ 多进程录制控制台 - @@ -39,13 +38,26 @@ video{position:absolute;inset:0;width:100%;height:100%} ⚪ 加载中... -

视频播放器(M3U8 / FLV)

- - -
- -
加载中...
+ + + + + + +

PM2 进程控制

@@ -57,70 +69,48 @@ video{position:absolute;inset:0;width:100%;height:100%}
正在加载状态与日志...
diff --git a/mpv.sh b/mpv.sh new file mode 100644 index 0000000..8269d53 --- /dev/null +++ b/mpv.sh @@ -0,0 +1,17 @@ +#!/bin/bash +mpv \ + --fs \ + --no-border \ + --vo=drm \ + --drm-device=/dev/dri/card0 \ + --hwdec=auto \ + --video-sync=display-resample \ + --untimed \ + --cache=no \ + --demuxer-lavf-o=ffflags=nobuffer \ + --demuxer-lavf-probesize=32 \ + --demuxer-lavf-analyzeduration=0 \ + --vf=setpts=PTS-STARTPTS \ + --no-audio \ + --loop=inf \ + 'srt://127.0.0.1:10080?streamid=#!::r=live/livestream,m=request&latency=10' diff --git a/obs.sh b/obs.sh index feb15f7..43754b1 100644 --- a/obs.sh +++ b/obs.sh @@ -1,4 +1,5 @@ +export DISPLAY=:0 ffplay -fflags nobuffer -flags low_delay -framedrop \ -probesize 32 -analyzeduration 0 -sync ext -infbuf \ -vf "setpts=PTS-STARTPTS" \ -'srt://127.0.0.1:10080?streamid=#!::r=live/livestream,m=request&latency=10' \ No newline at end of file +'srt://127.0.0.1:10080?streamid=#!::r=live/livestream,m=request&latency=10' diff --git a/obs1.sh b/obs1.sh new file mode 100644 index 0000000..7d54e81 --- /dev/null +++ b/obs1.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# 先确保有推流!(pm2 start tiktok/youtube 等,让 ffmpeg 推到 SRS 的 live/livestream) + +export SDL_VIDEODRIVER=kmsdrm # 尝试 SDL 的 DRM 驱动(直接 HDMI 输出,无需 DISPLAY) + +mpv \ + --fs \ + --no-border \ + --vo=drm \ + --drm-device=/dev/dri/card0 \ # 如果 card0 不对,改 card1(ls /dev/dri/ 查看) + --hwdec=auto \ + --video-sync=display-resample \ + --untimed \ + --cache=no \ + --demuxer-lavf-o=ffflags=nobuffer \ + --demuxer-lavf-probesize=32 \ + --demuxer-lavf-analyzeduration=0 \ + --vf=setpts=PTS-STARTPTS \ + --no-audio \ + --loop=inf \ + http://127.0.0.1:8081/live/livestream.flv # 先用 HTTP-FLV 测试(稳定,不依赖 SRT) + # 如果 HTTP-FLV 正常,再切回 SRT: + # 'srt://127.0.0.1:10080?streamid=#!::r=live/livestream,m=request&latency=10' diff --git a/web.py b/web.py index a10cc5a..4a9b478 100644 --- a/web.py +++ b/web.py @@ -1,4 +1,4 @@ -from fastapi import FastAPI, Query +from fastapi import FastAPI, Query, Request from fastapi.responses import FileResponse, JSONResponse from pathlib import Path import asyncio @@ -7,19 +7,21 @@ from fastapi.middleware.cors import CORSMiddleware app = FastAPI(title="多进程录制控制台") -# ---------------- 配置 ---------------- +# ---------------- 配置(修正为根目录结构) ---------------- BASE_DIR = Path(__file__).parent -DEFAULT_LOG_DIR = BASE_DIR.parent / ".pm2" / "logs" +CONFIG_DIR = BASE_DIR / "config" # 直接在根目录下 +DEFAULT_LOG_DIR = BASE_DIR / ".pm2" / "logs" # 直接在根目录下 + MAX_LOG_LINES = 300 -# 支持的进程列表(可扩展) +# 支持的进程列表 VALID_PROCESSES = {"tiktok", "youtube", "obs"} -# CORS +# CORS(支持 POST) app.add_middleware( CORSMiddleware, allow_origins=["*"], - allow_methods=["GET"], + allow_methods=["GET", "POST"], allow_headers=["*"], ) @@ -84,7 +86,7 @@ async def get_process_info(process: str) -> dict: out_path = value elif key == "err_log_path": err_path = value - # 备用默认路径(仅当 describe 未提供时) + # 备用默认路径(修正为根目录) if not out_path: out_path = str(DEFAULT_LOG_DIR / f"{process}-out.log") if not err_path: @@ -95,7 +97,41 @@ async def get_process_info(process: str) -> dict: "err_path": err_path, } -# ---------------- 路由 ---------------- +# ---------------- 配置路由 ---------------- +@app.get("/get_config") +async def get_config(process: str = Query(..., description="进程名")): + if process != "youtube": + return JSONResponse({"error": "仅 youtube 支持配置编辑"}, status_code=400) + + config_file = CONFIG_DIR / "youtube.ini" + if not config_file.exists(): + return {"content": "# youtube.ini 文件不存在,将创建空文件\n"} + try: + content = config_file.read_text(encoding="utf-8") + return {"content": content} + except Exception as e: + return JSONResponse({"error": f"读取失败: {str(e)}"}, status_code=500) + +@app.post("/save_config") +async def save_config(request: Request, process: str = Query(..., description="进程名")): + if process != "youtube": + return JSONResponse({"error": "仅 youtube 支持配置编辑"}, status_code=400) + + try: + data = await request.json() + content = data.get("content", "") + except: + return JSONResponse({"error": "无效的 JSON 数据"}, status_code=400) + + config_file = CONFIG_DIR / "youtube.ini" + try: + CONFIG_DIR.mkdir(parents=True, exist_ok=True) + config_file.write_text(content, encoding="utf-8") + return {"message": "配置保存成功"} + except Exception as e: + return JSONResponse({"error": f"保存失败: {str(e)}"}, status_code=500) + +# ---------------- 原有路由 ---------------- @app.get("/start") async def start(process: str = Query(..., description="进程名")): if process not in VALID_PROCESSES: diff --git a/web.sh b/web.sh index 3db8797..584810b 100644 --- a/web.sh +++ b/web.sh @@ -1 +1 @@ -uvicorn tiktokweb:app --host 0.0.0.0 --port 8000 --reload \ No newline at end of file +uvicorn web:app --host 0.0.0.0 --port 8000 --reload