Created
March 24, 2026 13:36
-
-
Save Leibinger015/2f5e99b5920c1a3b8ca14cfa0a27321b to your computer and use it in GitHub Desktop.
WebApp: For Smartphone and Tablets
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="de"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover"> | |
| <meta name="apple-mobile-web-app-capable" content="yes"> | |
| <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"> | |
| <title>auraTiVi</title> | |
| <link rel="apple-touch-icon" href="img/apple-touch-icon.png" /> | |
| <style> | |
| *, *::before, *::after { | |
| margin: 0; padding: 0; | |
| box-sizing: border-box; | |
| -webkit-tap-highlight-color: transparent; | |
| } | |
| button { border: none; cursor: pointer; outline: none; font-family: inherit; } | |
| html, body { | |
| width: 100%; height: 100%; | |
| background: #0e0e11; | |
| overflow: hidden; | |
| font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif; | |
| -webkit-font-smoothing: antialiased; | |
| color: #f2f2f7; | |
| } | |
| #app { | |
| display: flex; | |
| flex-direction: column; | |
| width: 100%; | |
| height: 100dvh; | |
| max-width: 560px; | |
| margin: 0 auto; | |
| background: #111113; | |
| position: relative; | |
| overflow: hidden; | |
| box-shadow: | |
| 0 0 0 1px rgba(255,255,255,0.07), | |
| 0 20px 60px rgba(0,0,0,0.85), | |
| 0 4px 20px rgba(0,0,0,0.6); | |
| } | |
| .safe-top { | |
| flex-shrink: 0; | |
| height: env(safe-area-inset-top, 0px); | |
| background: #000; | |
| } | |
| #video-wrap { | |
| flex-shrink: 0; | |
| position: relative; | |
| width: 100%; | |
| aspect-ratio: 16 / 9; | |
| background: #000; | |
| border-bottom: 2px solid #3a3a3e; | |
| box-shadow: 0 4px 20px rgba(0,0,0,0.7); | |
| z-index: 2; | |
| } | |
| #player { | |
| width: 100%; height: 100%; | |
| display: block; object-fit: cover; | |
| } | |
| #placeholder { | |
| position: absolute; inset: 0; | |
| background: #000; | |
| display: flex; flex-direction: column; | |
| align-items: center; justify-content: center; gap: 12px; | |
| transition: opacity 0.3s ease; | |
| } | |
| #placeholder.hidden { opacity: 0; pointer-events: none; } | |
| .spinner { | |
| width: 36px; height: 36px; | |
| border: 3px solid rgba(255,255,255,0.1); | |
| border-top-color: #d4622a; | |
| border-radius: 50%; | |
| animation: spin 0.75s linear infinite; | |
| } | |
| @keyframes spin { to { transform: rotate(360deg); } } | |
| #ph-name { color: rgba(255,255,255,0.38); font-size: 13px; font-weight: 500; } | |
| #overlay { | |
| position: absolute; inset: 0; | |
| display: flex; flex-direction: column; | |
| justify-content: space-between; | |
| opacity: 0; pointer-events: none; | |
| transition: opacity 0.22s ease; | |
| background: linear-gradient(180deg, | |
| rgba(0,0,0,0.52) 0%, transparent 30%, | |
| transparent 60%, rgba(0,0,0,0.65) 100%); | |
| } | |
| #overlay.show { opacity: 1; pointer-events: all; } | |
| .ov-top { | |
| display: flex; align-items: center; | |
| justify-content: space-between; padding: 10px 12px; | |
| } | |
| .vid-icon-btn { | |
| width: 32px; height: 32px; | |
| background: rgba(0,0,0,0.38); | |
| border: 1px solid rgba(255,255,255,0.15); | |
| border-radius: 9px; color: #fff; | |
| display: flex; align-items: center; justify-content: center; | |
| box-shadow: 0 2px 8px rgba(0,0,0,0.5); | |
| backdrop-filter: blur(10px); | |
| -webkit-backdrop-filter: blur(10px); | |
| } | |
| .live-badge { | |
| display: flex; align-items: center; gap: 5px; | |
| background: rgba(0,0,0,0.42); | |
| border: 1px solid rgba(255,255,255,0.14); | |
| border-radius: 8px; padding: 4px 9px; | |
| box-shadow: 0 2px 8px rgba(0,0,0,0.4); | |
| backdrop-filter: blur(10px); | |
| -webkit-backdrop-filter: blur(10px); | |
| } | |
| .live-dot { | |
| width: 7px; height: 7px; | |
| background: #d4622a; border-radius: 50%; | |
| box-shadow: 0 0 6px #d4622a; | |
| animation: livepulse 2s ease-in-out infinite; | |
| } | |
| @keyframes livepulse { 0%,100%{opacity:1} 50%{opacity:0.35} } | |
| .live-text { color: #fff; font-size: 11px; font-weight: 700; letter-spacing: 0.8px; } | |
| .ch-badge { | |
| background: #d4622a; color: #fff; | |
| font-size: 11px; font-weight: 700; | |
| padding: 4px 10px; border-radius: 8px; | |
| letter-spacing: 0.4px; | |
| box-shadow: 0 2px 10px rgba(212,98,42,0.45); | |
| } | |
| .ov-center { | |
| display: flex; align-items: center; | |
| justify-content: center; gap: 28px; | |
| } | |
| .ov-ctrl { | |
| width: 46px; height: 46px; | |
| background: rgba(0,0,0,0.38); | |
| border: 1px solid rgba(255,255,255,0.16); | |
| border-radius: 50%; color: #fff; | |
| display: flex; align-items: center; justify-content: center; | |
| box-shadow: 0 3px 12px rgba(0,0,0,0.5); | |
| backdrop-filter: blur(12px); | |
| -webkit-backdrop-filter: blur(12px); | |
| transition: transform 0.1s; | |
| } | |
| .ov-ctrl:active { transform: scale(0.88); } | |
| .ov-ctrl.big { | |
| width: 58px; height: 58px; | |
| background: rgba(255,255,255,0.16); | |
| border-color: rgba(255,255,255,0.28); | |
| box-shadow: 0 6px 22px rgba(0,0,0,0.55); | |
| } | |
| .ov-bottom { padding: 8px 12px 10px; } | |
| .prog-row { display: flex; align-items: center; gap: 8px; margin-bottom: 5px; } | |
| .prog-track { | |
| flex: 1; height: 3px; | |
| background: rgba(255,255,255,0.22); | |
| border-radius: 3px; overflow: hidden; | |
| } | |
| .prog-fill { height: 100%; width: 99%; background: #fff; border-radius: 3px; } | |
| .t-lbl { color: rgba(255,255,255,0.75); font-size: 11px; font-variant-numeric: tabular-nums; } | |
| .meta-row { display: flex; align-items: center; justify-content: space-between; } | |
| #prog-title { | |
| color: rgba(255,255,255,0.6); | |
| font-size: 10px; font-weight: 600; | |
| text-transform: uppercase; letter-spacing: 0.9px; | |
| } | |
| .meta-btns { display: flex; gap: 10px; } | |
| .meta-btn { background: none; color: rgba(255,255,255,0.6); font-size: 15px; padding: 2px; } | |
| #remote { | |
| flex: 1; | |
| display: flex; flex-direction: column; | |
| min-height: 0; overflow: hidden; | |
| position: relative; | |
| background: | |
| repeating-linear-gradient( | |
| 92deg, | |
| rgba(255,255,255,0.012) 0px, | |
| rgba(255,255,255,0.012) 1px, | |
| transparent 1px, | |
| transparent 3px | |
| ), | |
| linear-gradient(180deg, | |
| #2e2e33 0%, | |
| #262629 40%, | |
| #212124 70%, | |
| #1c1c1f 100% | |
| ); | |
| border-top: 1px solid rgba(255,255,255,0.13); | |
| box-shadow: | |
| inset 0 1px 0 rgba(255,255,255,0.09), | |
| inset 0 -1px 0 rgba(0,0,0,0.5); | |
| } | |
| #remote::before { | |
| content: ""; | |
| position: absolute; | |
| inset: 0; | |
| background: radial-gradient(ellipse 70% 55% at 50% 38%, | |
| rgba(212,98,42,0.07) 0%, | |
| transparent 70% | |
| ); | |
| pointer-events: none; | |
| } | |
| .remote-body { flex: 1; display: flex; min-height: 0; position: relative; z-index: 1; } | |
| .col-divider { | |
| width: 1px; flex-shrink: 0; | |
| background: linear-gradient(180deg, | |
| transparent 0%, | |
| rgba(255,255,255,0.09) 20%, | |
| rgba(255,255,255,0.09) 80%, | |
| transparent 100% | |
| ); | |
| } | |
| .remote-col { | |
| flex: 1; | |
| display: flex; flex-direction: column; | |
| align-items: center; justify-content: center; | |
| gap: 12px; padding: 18px 14px; | |
| } | |
| .ch-cluster { | |
| display: flex; align-items: center; gap: 6px; | |
| background: linear-gradient(180deg, #141416 0%, #1e1e22 100%); | |
| border: 1px solid rgba(0,0,0,0.7); | |
| border-radius: 50px; padding: 10px 12px; | |
| box-shadow: | |
| inset 0 2px 6px rgba(0,0,0,0.7), | |
| inset 0 1px 0 rgba(0,0,0,0.5), | |
| 0 1px 0 rgba(255,255,255,0.09), | |
| 0 4px 14px rgba(0,0,0,0.5); | |
| } | |
| .logo-display { | |
| position: relative; | |
| width: 146px; | |
| height: 146px; | |
| flex-shrink: 0; | |
| border-radius: 14px; | |
| background: linear-gradient(145deg, #141416 0%, #1a1a1e 60%, #141416 100%); | |
| border: 1px solid rgba(0,0,0,0.7); | |
| overflow: hidden; | |
| box-shadow: | |
| inset 0 3px 8px rgba(0,0,0,0.8), | |
| inset 0 1px 0 rgba(0,0,0,0.6), | |
| inset 0 -1px 0 rgba(255,255,255,0.03), | |
| 0 1px 0 rgba(255,255,255,0.07), | |
| 0 4px 14px rgba(0,0,0,0.5); | |
| } | |
| .logo-display::before { | |
| content: ""; | |
| position: absolute; inset: 0; | |
| background: radial-gradient(ellipse 70% 60% at 50% 50%, | |
| rgba(212,98,42,0.09) 0%, | |
| transparent 70%); | |
| pointer-events: none; | |
| z-index: 0; | |
| } | |
| .logo-display::after { | |
| content: ""; | |
| position: absolute; | |
| top: 0; left: 0; right: 0; | |
| height: 40%; | |
| background: linear-gradient(180deg, | |
| rgba(255,255,255,0.045) 0%, | |
| transparent 100%); | |
| border-radius: 14px 14px 0 0; | |
| pointer-events: none; | |
| z-index: 0; | |
| } | |
| .logo-display img { | |
| position: absolute; | |
| top: 50%; left: 50%; | |
| transform: translate(-50%, -50%); | |
| width: 72%; height: 72%; | |
| object-fit: contain; | |
| z-index: 1; | |
| filter: drop-shadow(0 2px 6px rgba(0,0,0,0.7)); | |
| transition: opacity 0.25s ease; | |
| } | |
| .logo-display img.hidden { opacity: 0; } | |
| .logo-placeholder { | |
| position: absolute; | |
| top: 50%; left: 50%; | |
| transform: translate(-50%, -50%); | |
| z-index: 1; | |
| color: #d4622a; | |
| opacity: 0.55; | |
| display: flex; align-items: center; justify-content: center; | |
| } | |
| .ch-arrow { | |
| width: 58px; height: 52px; | |
| background: linear-gradient(145deg, #2e2e32 0%, #222226 55%, #1a1a1e 100%); | |
| border: 1px solid rgba(0,0,0,0.6); | |
| border-radius: 40px; | |
| color: #d4622a; | |
| display: flex; align-items: center; justify-content: center; | |
| box-shadow: | |
| 0 4px 0 rgba(0,0,0,0.55), | |
| 0 6px 16px rgba(0,0,0,0.5), | |
| inset 0 1px 0 rgba(255,255,255,0.1); | |
| transition: transform 0.1s, box-shadow 0.1s; | |
| -webkit-user-select: none; | |
| } | |
| .ch-arrow:active { | |
| transform: translateY(3px); | |
| box-shadow: | |
| 0 1px 0 rgba(0,0,0,0.55), | |
| 0 2px 6px rgba(0,0,0,0.4), | |
| inset 0 1px 0 rgba(255,255,255,0.06); | |
| } | |
| .btn-grid { | |
| display: grid; | |
| grid-template-columns: 1fr 1fr; | |
| gap: 14px 16px; | |
| align-items: center; | |
| justify-items: center; | |
| } | |
| .btn-cell { | |
| display: flex; flex-direction: column; | |
| align-items: center; gap: 7px; | |
| } | |
| .remote-lbl { | |
| color: #4a4a4f; | |
| font-size: 9px; font-weight: 600; | |
| text-transform: uppercase; letter-spacing: 1.1px; | |
| text-shadow: 0 1px 0 rgba(0,0,0,0.8); | |
| } | |
| .sub-btn { | |
| width: 64px; height: 64px; | |
| border-radius: 50%; | |
| color: #fff; | |
| font-size: 28px; font-weight: 400; font-style: normal; | |
| letter-spacing: 0; | |
| display: flex; align-items: center; justify-content: center; | |
| transition: transform 0.1s, box-shadow 0.1s; | |
| -webkit-user-select: none; | |
| background: linear-gradient(145deg, #f0804a 0%, #d4622a 55%, #b84e1e 100%); | |
| border: 1px solid rgba(0,0,0,0.4); | |
| box-shadow: | |
| 0 5px 0 rgba(0,0,0,0.5), | |
| 0 8px 24px rgba(212,98,42,0.55), | |
| 0 2px 8px rgba(0,0,0,0.5), | |
| inset 0 1px 0 rgba(255,255,255,0.28), | |
| inset 0 -1px 0 rgba(0,0,0,0.2); | |
| } | |
| .sub-btn:active { | |
| transform: translateY(3px); | |
| box-shadow: | |
| 0 2px 0 rgba(0,0,0,0.5), | |
| 0 4px 12px rgba(212,98,42,0.4), | |
| inset 0 1px 0 rgba(255,255,255,0.15); | |
| } | |
| .sub-btn.off { | |
| color: #4a4a4f; | |
| background: linear-gradient(145deg, #323236 0%, #252528 55%, #1e1e21 100%); | |
| box-shadow: | |
| 0 5px 0 rgba(0,0,0,0.55), | |
| 0 8px 20px rgba(0,0,0,0.5), | |
| inset 0 1px 0 rgba(255,255,255,0.1), | |
| inset 0 -1px 0 rgba(0,0,0,0.3); | |
| } | |
| .ch-bar-wrap { | |
| flex-shrink: 0; | |
| position: relative; z-index: 1; | |
| background: linear-gradient(180deg, #0e0e11 0%, #111114 100%); | |
| border-top: 1px solid rgba(0,0,0,0.8); | |
| box-shadow: | |
| inset 0 1px 0 rgba(255,255,255,0.05), | |
| 0 -6px 20px rgba(0,0,0,0.5); | |
| padding: 10px 0; | |
| padding-bottom: calc(12px + env(safe-area-inset-bottom, 0px)); | |
| } | |
| .ch-bar { | |
| display: flex; gap: 8px; | |
| overflow-x: auto; | |
| padding: 2px 14px 4px; | |
| scrollbar-width: none; | |
| scroll-snap-type: x mandatory; | |
| -webkit-overflow-scrolling: touch; | |
| } | |
| .ch-bar::-webkit-scrollbar { display: none; } | |
| .ch-pill { | |
| flex-shrink: 0; | |
| scroll-snap-align: start; | |
| background: linear-gradient(180deg, #2a2a2e 0%, #1e1e22 100%); | |
| border: 1px solid rgba(255,255,255,0.1); | |
| border-radius: 13px; | |
| padding: 8px 14px 6px; | |
| color: #aeaeb2; | |
| font-size: 12px; font-weight: 700; | |
| white-space: nowrap; | |
| -webkit-user-select: none; | |
| display: flex; flex-direction: column; align-items: center; | |
| min-width: 54px; | |
| box-shadow: | |
| 0 3px 0 rgba(0,0,0,0.5), | |
| 0 5px 14px rgba(0,0,0,0.5), | |
| inset 0 1px 0 rgba(255,255,255,0.09); | |
| transition: transform 0.15s, box-shadow 0.15s; | |
| } | |
| .ch-pill.active { | |
| background: linear-gradient(145deg, #f0804a 0%, #d4622a 60%, #b84e1e 100%); | |
| border-color: rgba(240,128,74,0.4); | |
| color: #fff; | |
| box-shadow: | |
| 0 3px 0 rgba(0,0,0,0.4), | |
| 0 6px 22px rgba(212,98,42,0.55), | |
| inset 0 1px 0 rgba(255,255,255,0.28); | |
| } | |
| .ch-pill:active { | |
| transform: translateY(2px); | |
| box-shadow: 0 1px 0 rgba(0,0,0,0.5), 0 2px 6px rgba(0,0,0,0.4); | |
| } | |
| .pill-meta { | |
| display: flex; align-items: center; justify-content: center; | |
| gap: 4px; margin-top: 3px; line-height: 1; | |
| } | |
| .pill-tag { | |
| font-size: 8px; font-weight: 700; opacity: 0.55; | |
| letter-spacing: 0.5px; text-transform: uppercase; | |
| } | |
| .pill-lock { | |
| display: flex; align-items: center; opacity: 0.55; | |
| } | |
| .safe-bottom { | |
| flex-shrink: 0; | |
| height: env(safe-area-inset-bottom, 0px); | |
| background: #111113; | |
| } | |
| body::after { | |
| content: ""; | |
| display: block; | |
| position: fixed; | |
| bottom: 0; left: 0; right: 0; | |
| height: env(safe-area-inset-bottom, 0px); | |
| background: #0e0e11; | |
| z-index: 10000; | |
| pointer-events: none; | |
| } | |
| #rotate-warning { | |
| display: none; | |
| position: fixed; inset: 0; z-index: 9999; | |
| background: #0d0d0f; | |
| flex-direction: column; | |
| align-items: center; justify-content: center; | |
| gap: 20px; | |
| padding: 40px; | |
| text-align: center; | |
| } | |
| .rotate-icon { | |
| font-size: 56px; | |
| animation: rotateHint 2s ease-in-out infinite; | |
| } | |
| @keyframes rotateHint { | |
| 0%,100% { transform: rotate(0deg); } | |
| 40% { transform: rotate(-90deg); } | |
| 60% { transform: rotate(-90deg); } | |
| } | |
| .rotate-title { | |
| color: #f2f2f7; font-size: 18px; font-weight: 700; line-height: 1.35; | |
| } | |
| .rotate-sub { | |
| color: #636366; font-size: 14px; line-height: 1.5; | |
| } | |
| #fs-video::cue { display: none; } | |
| #fs-overlay { | |
| display: none; | |
| position: fixed; inset: 0; z-index: 8000; | |
| background: #000; | |
| align-items: center; justify-content: center; | |
| } | |
| #fs-overlay.active { display: flex; } | |
| #fs-overlay #player { | |
| width: 100%; height: 100%; | |
| object-fit: contain; | |
| display: block; | |
| } | |
| #fs-close { | |
| position: absolute; | |
| top: calc(env(safe-area-inset-top, 16px) + 10px); | |
| right: 16px; | |
| width: 38px; height: 38px; | |
| background: rgba(0,0,0,0.55); | |
| border: 1.5px solid rgba(255,255,255,0.25); | |
| border-radius: 50%; | |
| color: #fff; font-size: 18px; | |
| display: flex; align-items: center; justify-content: center; | |
| cursor: pointer; | |
| backdrop-filter: blur(12px); | |
| -webkit-backdrop-filter: blur(12px); | |
| box-shadow: 0 2px 10px rgba(0,0,0,0.5); | |
| z-index: 8001; | |
| } | |
| #fs-close:active { transform: scale(0.9); } | |
| #toast { | |
| position: fixed; | |
| top: calc(env(safe-area-inset-top, 0px) + 12px); | |
| left: 50%; transform: translateX(-50%) translateY(-8px); | |
| background: rgba(26,26,28,0.96); | |
| backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px); | |
| border: 1px solid rgba(255,255,255,0.1); | |
| color: #f2f2f7; font-size: 13px; font-weight: 500; | |
| padding: 10px 18px; border-radius: 14px; | |
| box-shadow: 0 6px 24px rgba(0,0,0,0.6); | |
| opacity: 0; pointer-events: none; | |
| transition: opacity 0.25s, transform 0.25s; | |
| z-index: 9999; max-width: 88vw; text-align: center; | |
| } | |
| #toast.show { opacity: 1; transform: translateX(-50%) translateY(0); } | |
| @media (min-width: 560px) { | |
| #app { | |
| border-left: 1px solid rgba(255,255,255,0.06); | |
| border-right: 1px solid rgba(255,255,255,0.06); | |
| } | |
| } | |
| @media (min-width: 768px) { | |
| html { | |
| height: 100%; | |
| background: #0e0e11; | |
| overflow: hidden; | |
| } | |
| body { | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| width: 100%; | |
| height: 100%; | |
| min-height: 100vh; | |
| overflow: hidden; | |
| background-color: #0e0e11; | |
| background-image: | |
| radial-gradient(ellipse 80% 60% at 50% 30%, | |
| rgba(212,98,42,0.06) 0%, transparent 60%), | |
| radial-gradient(ellipse 60% 50% at 50% 90%, | |
| rgba(0,176,186,0.04) 0%, transparent 60%), | |
| linear-gradient(180deg, #1a1a1e 0%, #111113 40%, #0e0e11 100%); | |
| } | |
| body::after { display: none !important; height: 0 !important; content: none !important; background: transparent !important; } | |
| #app-scaler { | |
| transform-origin: center center; | |
| padding: 3px; | |
| border-radius: 22px; | |
| background: linear-gradient(180deg, | |
| #d4622a 0%, | |
| #b85c28 30%, | |
| #0090a0 70%, | |
| #00b0ba 100% | |
| ); | |
| box-shadow: | |
| 0 -6px 24px rgba(212,98,42,0.35), | |
| 0 6px 24px rgba(0,176,186,0.25), | |
| 0 20px 60px rgba(0,0,0,0.7), | |
| 0 4px 20px rgba(0,0,0,0.5); | |
| flex-shrink: 0; | |
| } | |
| #app { | |
| width: 460px !important; | |
| max-width: 460px !important; | |
| height: 720px !important; | |
| border-radius: 20px; | |
| overflow: hidden; | |
| margin: 0; | |
| box-shadow: none; | |
| } | |
| .safe-top { height: 0px !important; } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div id="app-scaler"> | |
| <div id="app"> | |
| <div class="safe-top"></div> | |
| <div id="video-wrap" onclick="tapVideo()"> | |
| <video id="player" playsinline webkit-playsinline></video> | |
| <div id="placeholder"> | |
| <div class="spinner"></div> | |
| <div id="ph-name">Sender wird geladen ...</div> | |
| </div> | |
| <div id="overlay"> | |
| <div class="ov-top"> | |
| <button class="vid-icon-btn" onclick="event.stopPropagation();goFS()"> | |
| <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2.5"> | |
| <path d="M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3"/> | |
| </svg> | |
| </button> | |
| <div class="live-badge"> | |
| <div class="live-dot"></div> | |
| <span class="live-text">LIVE</span> | |
| </div> | |
| <span class="ch-badge" id="ch-badge">--</span> | |
| </div> | |
| <div class="ov-center" onclick="event.stopPropagation()"> | |
| <button class="ov-ctrl" onclick="seek(-10)"> | |
| <svg width="20" height="20" viewBox="0 0 24 24" fill="white"> | |
| <path d="M12 5V1L7 6l5 5V7c3.31 0 6 2.69 6 6s-2.69 6-6 6-6-2.69-6-6H4c0 4.42 3.58 8 8 8s8-3.58 8-8-3.58-8-8-8z"/> | |
| </svg> | |
| </button> | |
| <button class="ov-ctrl big" id="play-btn" onclick="togglePlay()"> | |
| <svg id="play-icon" width="26" height="26" viewBox="0 0 24 24" fill="white"> | |
| <path d="M6 4h4v16H6zM14 4h4v16h-4z"/> | |
| </svg> | |
| </button> | |
| <button class="ov-ctrl" onclick="seek(10)"> | |
| <svg width="20" height="20" viewBox="0 0 24 24" fill="white"> | |
| <path d="M12 5V1l5 5-5 5V7c-3.31 0-6 2.69-6 6s2.69 6 6 6 6-2.69 6-6h2c0 4.42-3.58 8-8 8s-8-3.58-8-8 3.58-8 8-8z"/> | |
| </svg> | |
| </button> | |
| </div> | |
| <div class="ov-bottom" onclick="event.stopPropagation()"> | |
| <div class="prog-row"> | |
| <span class="t-lbl">LIVE</span> | |
| <div class="prog-track"><div class="prog-fill"></div></div> | |
| <span class="t-lbl">-0:05</span> | |
| </div> | |
| <div class="meta-row"> | |
| <span id="prog-title">--</span> | |
| <div class="meta-btns"> | |
| <button class="meta-btn">⏤</button> | |
| <button class="meta-btn">···</button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div id="remote"> | |
| <div class="remote-body"> | |
| <div class="remote-col"> | |
| <div class="ch-cluster"> | |
| <button class="ch-arrow" onclick="chStep(-1)"> | |
| <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="#d4622a" stroke-width="2.5" stroke-linecap="round"><path d="M15 18l-6-6 6-6"/></svg> | |
| </button> | |
| <button class="ch-arrow" onclick="chStep(1)"> | |
| <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="#d4622a" stroke-width="2.5" stroke-linecap="round"><path d="M9 18l6-6-6-6"/></svg> | |
| </button> | |
| </div> | |
| <span class="remote-lbl">Kanal</span> | |
| <div class="logo-display" id="logo-display"> | |
| <img id="logo-img" src="" alt="" class="hidden"> | |
| <div class="logo-placeholder" id="logo-ph" style="display:flex;"> | |
| <svg width="38" height="38" viewBox="0 0 24 24" fill="none" stroke="#d4622a" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"> | |
| <rect x="2" y="7" width="20" height="13" rx="2"/> | |
| <path d="M8 7V5a2 2 0 0 1 4 0v2"/> | |
| <circle cx="12" cy="13.5" r="2.5" fill="#d4622a" stroke="none" opacity="0.6"/> | |
| </svg> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="col-divider"></div> | |
| <div class="remote-col"> | |
| <div class="btn-grid"> | |
| <div class="btn-cell"> | |
| <button class="sub-btn off" id="mute-btn" onclick="toggleMute()"> | |
| <svg id="mute-icon" width="22" height="22" viewBox="0 0 24 24"> | |
| <path d="M11 5L6 9H2v6h4l5 4V5z" fill="#636366"/> | |
| <path d="M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07" fill="none" stroke="#636366" stroke-width="2" stroke-linecap="round"/> | |
| </svg> | |
| </button> | |
| <span class="remote-lbl">Ton</span> | |
| </div> | |
| <div class="btn-cell"> | |
| <button class="sub-btn off" id="sub-btn" onclick="toggleSub()">🅤</button> | |
| <span class="remote-lbl">Untertitel</span> | |
| </div> | |
| <div class="btn-cell"> | |
| <button class="sub-btn off" id="fs-btn" onclick="openFS()" style="font-size:22px;"> | |
| <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"> | |
| <path d="M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3"/> | |
| </svg> | |
| </button> | |
| <span class="remote-lbl">Vollbild</span> | |
| </div> | |
| <div class="btn-cell"> | |
| <button class="sub-btn off" id="info-btn" onclick="openInfo()" style="font-size:22px;">ⓘ</button> | |
| <span class="remote-lbl">Info</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="ch-bar-wrap"> | |
| <div class="ch-bar" id="ch-bar"></div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div id="info-backdrop" onclick="closeInfo()" style="display:none; position:fixed; inset:0; z-index:9000; background:rgba(0,0,0,0.55); backdrop-filter:blur(4px); -webkit-backdrop-filter:blur(4px);"></div> | |
| <div id="info-modal" onclick="closeInfo()" style=" | |
| display:none; position:fixed; left:50%; bottom:0; z-index:9001; | |
| width:100%; max-width:560px; transform:translateX(-50%) translateY(100%); | |
| background:#1c1c1f; border-radius:20px 20px 0 0; | |
| border-top:1px solid rgba(255,255,255,0.1); | |
| box-shadow:0 -8px 40px rgba(0,0,0,0.7); | |
| transition:transform 0.35s cubic-bezier(0.32,0.72,0,1); | |
| padding:24px 24px calc(24px + env(safe-area-inset-bottom,0px)); | |
| "> | |
| <div style="width:36px;height:4px;background:rgba(255,255,255,0.2);border-radius:2px;margin:0 auto 22px;"></div> | |
| <div style="display:flex;align-items:center;justify-content:space-between;gap:12px;"> | |
| <div style="font-size:17px;font-weight:700;color:#d4622a;margin-bottom:4px;">auraTiVi by anb030 <span style="color:#636366;font-weight:400;font-size:12px;"><br> | |
| • Version: 2.265 (260313)<br> | |
| • M3U-Liste / TV-Sender: 260313 / 28</span></div> | |
| <img src="img/app_icon.png" alt="Icon" style="width:64px;height:64px;border-radius:14px;flex-shrink:0;box-shadow:0 4px 14px rgba(0,0,0,0.5);"> | |
| </div> | |
| <div style="width:100%;height:1px;background:rgba(255,255,255,0.08);margin:14px 0;"></div> | |
| <div style="font-size:14px;color:#aeaeb2;line-height:2;"> | |
| <b style="color:#f2f2f7;">Die Bedienelemente:</b><br> | |
| <span style="display:flex;align-items:center;gap:10px;margin-top:6px;"> | |
| <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#aeaeb2" stroke-width="2" stroke-linecap="round"><path d="M15 18l-6-6 6-6"/></svg> | |
| <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#aeaeb2" stroke-width="2" stroke-linecap="round"><path d="M9 18l6-6-6-6"/></svg> | |
| <span>Senderauswahltasten [Key: ↑←↓→]</span> | |
| </span> | |
| <span style="display:flex;align-items:center;gap:10px;margin-top:6px;"> | |
| <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#aeaeb2" stroke-width="2" stroke-linecap="round"><path d="M11 5L6 9H2v6h4l5 4V5z"/><path d="M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07"/></svg> | |
| <span>Ton AN / AUS [Key: M]</span> | |
| </span> | |
| <span style="display:flex;align-items:center;gap:10px;margin-top:6px;"> | |
| <span style="font-size:18px;line-height:1;">🅤</span> | |
| <span>Untertitel AN / AUS [Key: U]</span> | |
| </span> | |
| <span style="display:flex;align-items:center;gap:10px;margin-top:6px;"> | |
| <span style="font-size:18px;line-height:1;">▶</span> | |
| <span>Wiedergabe / Pause [Key: Space]</span> | |
| </span> | |
| <span style="display:flex;align-items:center;gap:10px;margin-top:6px;"> | |
| <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#aeaeb2" stroke-width="2" stroke-linecap="round"><path d="M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3"/></svg> | |
| <span>Vollbild [Key: F], mit X schließen [Key: ESC]</span> | |
| </span> | |
| <span style="display:block;margin-top:8px;color:#636366;font-size:12px;">ⓘ Im <strong>Vollbildmodus</strong> ist das Gerät <strong>drehbar</strong>! Die <strong>Nutzung</strong> dieser GitHub <a href="https://github.com/iptv-org/iptv/tree/master/streams" style="color:#00b0ba; text-decoration:none;">M3U-Listen</a> und <a href="https://github.com/tv-logo/tv-logos/tree/main/countries/germany" style="color:#00b0ba; text-decoration:none;">TV-Logos</a> sind rechtlich eine <strong>Grauzone</strong>.</span> | |
| </div> | |
| <div style="width:100%;height:1px;background:rgba(255,255,255,0.08);margin:14px 0;"></div> | |
| <div style="font-size:12px;color:#636366;text-align:center;">Designed for modern iOS experience!<br>Developed with ♥ by…<br>© <a href="https://anb030.de/a/" target="_blank" style="color:#00b0ba;text-decoration:none;">anb030.de</a> | |
| <br><br> | |
| <img src="img/webappready.png" alt="auraTiVi is WebApp Ready" style="max-width:80px;opacity:0.8;"> | |
| </div> | |
| </div> | |
| <div id="rotate-warning"> | |
| <div class="rotate-icon">📱</div> | |
| <div class="rotate-title">Bitte Gerät drehen</div> | |
| <div class="rotate-sub">Diese WebApp funktioniert nur im Hochformat / Portrait Modus.</div> | |
| </div> | |
| <div id="fs-overlay"> | |
| <button id="fs-close" onclick="closeFS()"> | |
| <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="3" stroke-linecap="round"><path d="M18 6L6 18M6 6l12 12"/></svg> | |
| </button> | |
| </div> | |
| <div id="toast"></div> | |
| <script> | |
| async function loadM3U() { | |
| try { | |
| const r = await fetch("mytv.m3u"); | |
| if (!r.ok) throw new Error(); | |
| return parseM3U(await r.text()); | |
| } catch { | |
| showToast("⚠ mytv.m3u konnte nicht geladen werden"); | |
| return []; | |
| } | |
| } | |
| function parseM3U(txt) { | |
| const lines = txt.split("\n").map(l => l.trim()).filter(Boolean); | |
| const out = []; | |
| for (let i = 0; i < lines.length; i++) { | |
| if (!lines[i].startsWith("#EXTINF")) continue; | |
| const url = lines[i + 1]; | |
| if (!url || url.startsWith("#")) continue; | |
| const m = lines[i].match(/,(.+)$/); | |
| const raw = m ? m[1].trim() : "Sender"; | |
| const geo = /\[geo-blocked\]/i.test(raw); | |
| const logoAttr = lines[i].match(/tvg-logo="([^"]+)"/); | |
| const logo = logoAttr ? logoAttr[1].trim() : null; | |
| const shortMatch = raw.match(/\[short:([^\]]+)\]/i); | |
| const langMatch = raw.match(/\[lang:([^\]]+)\]/i); | |
| const qualityMatch = raw.match(/\[quality:([^\]]+)\]/i); | |
| const short = shortMatch ? shortMatch[1].trim() : autoShort(raw); | |
| const lang = langMatch ? langMatch[1].trim().toUpperCase() : null; | |
| const quality = qualityMatch ? qualityMatch[1].trim().toUpperCase() : null; | |
| const name = raw.replace(/\s*\[.*?\]/g, "").replace(/\s*\(.*?\)/g, "").trim(); | |
| out.push({ name, short, url, geo, lang, quality, logo }); | |
| i++; | |
| } | |
| return out; | |
| } | |
| function autoShort(raw) { | |
| const clean = raw.replace(/\s*\[.*?\]/g, "").trim(); | |
| return clean.split(/[\s\-]/)[0].slice(0, 7); | |
| } | |
| let channels=[], curIdx=-1, muted=false, subOn=false, hls=null, oTimer=null; | |
| const video = document.getElementById("player"); | |
| const ph = document.getElementById("placeholder"); | |
| const phName = document.getElementById("ph-name"); | |
| const overlay = document.getElementById("overlay"); | |
| const chBadge = document.getElementById("ch-badge"); | |
| const progTit = document.getElementById("prog-title"); | |
| const playIco = document.getElementById("play-icon"); | |
| const muteBtn = document.getElementById("mute-btn"); | |
| const muteIco = document.getElementById("mute-icon"); | |
| const subBtn = document.getElementById("sub-btn"); | |
| const chBar = document.getElementById("ch-bar"); | |
| function buildBar() { | |
| chBar.innerHTML = ""; | |
| channels.forEach((ch, i) => { | |
| const b = document.createElement("button"); | |
| b.className = "ch-pill"; | |
| b.id = "pill" + i; | |
| const metaParts = []; | |
| if (ch.lang) metaParts.push(`<span class="pill-tag">${ch.lang}</span>`); | |
| if (ch.geo) metaParts.push(`<span class="pill-lock"><svg width="8" height="9" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg></span>`); | |
| if (ch.quality) metaParts.push(`<span class="pill-tag">${ch.quality}</span>`); | |
| const metaRow = metaParts.length | |
| ? `<span class="pill-meta">${metaParts.join("")}</span>` | |
| : ""; | |
| b.innerHTML = ch.short + metaRow; | |
| b.onclick = () => loadCh(i); | |
| chBar.appendChild(b); | |
| }); | |
| } | |
| function ensureHls(cb) { | |
| if (window.Hls) return cb(); | |
| const s = document.createElement("script"); | |
| s.src = "https://cdnjs.cloudflare.com/ajax/libs/hls.js/1.4.12/hls.min.js"; | |
| s.onload = cb; | |
| document.head.appendChild(s); | |
| } | |
| function loadCh(idx) { | |
| if (idx === curIdx) return; | |
| curIdx = idx; | |
| const ch = channels[idx]; | |
| document.querySelectorAll(".ch-pill").forEach((p,i) => p.classList.toggle("active", i===idx)); | |
| document.getElementById("pill"+idx)?.scrollIntoView({behavior:"smooth",inline:"center",block:"nearest"}); | |
| chBadge.textContent = ch.short; | |
| progTit.textContent = ch.name; | |
| const logoImg = document.getElementById("logo-img"); | |
| const logoPh = document.getElementById("logo-ph"); | |
| logoImg.onload = null; | |
| logoImg.onerror = null; | |
| logoImg.src = ""; | |
| logoImg.classList.add("hidden"); | |
| if (ch.logo) { | |
| logoPh.style.display = "none"; | |
| logoImg.onload = () => logoImg.classList.remove("hidden"); | |
| logoImg.onerror = () => { | |
| logoImg.classList.add("hidden"); | |
| logoPh.style.display = "flex"; | |
| }; | |
| logoImg.src = ch.logo; | |
| } else { | |
| logoPh.style.display = "flex"; | |
| } | |
| phName.textContent = ch.name; | |
| ph.classList.remove("hidden"); | |
| ensureHls(() => { | |
| if (hls) { hls.destroy(); hls = null; } | |
| video.src = ""; | |
| if (Hls.isSupported()) { | |
| hls = new Hls({lowLatencyMode:true, enableWorker:true}); | |
| hls.loadSource(ch.url); | |
| hls.attachMedia(video); | |
| hls.on(Hls.Events.MANIFEST_PARSED, () => { | |
| ph.classList.add("hidden"); | |
| video.play().catch(()=>{}); | |
| }); | |
| hls.on(Hls.Events.SUBTITLE_TRACK_LOADED, () => { | |
| for (const t of video.textTracks) t.mode = subOn ? "showing" : "hidden"; | |
| }); | |
| hls.on(Hls.Events.ERROR, (_, data) => { | |
| if (data.fatal) { | |
| switch (data.type) { | |
| case Hls.ErrorTypes.NETWORK_ERROR: | |
| showToast("⚠ Netzwerkfehler beim Stream"); | |
| hls.startLoad(); | |
| break; | |
| case Hls.ErrorTypes.MEDIA_ERROR: | |
| showToast("⚠ Media Fehler – versuche zu reparieren"); | |
| hls.recoverMediaError(); | |
| break; | |
| default: | |
| showToast("⚠ Stream nicht verfügbar" + (ch.geo ? " (Geo-blockiert)" : "")); | |
| hls.destroy(); | |
| hls = null; | |
| ph.classList.remove("hidden"); | |
| break; | |
| } | |
| } | |
| }); | |
| } else if (video.canPlayType("application/vnd.apple.mpegurl")) { | |
| video.src = ch.url; | |
| video.onloadedmetadata = () => { | |
| ph.classList.add("hidden"); | |
| for (const t of video.textTracks) t.mode = subOn ? "showing" : "hidden"; | |
| video.play().catch(()=>{}); video.onloadedmetadata=null; | |
| }; | |
| } else { showToast("Dein Browser unterstützt kein HLS"); } | |
| }); | |
| } | |
| function togglePlay() { video.paused ? video.play() : video.pause(); } | |
| function updatePlayIcon() { | |
| playIco.innerHTML = video.paused | |
| ? "<path d=\"M8 5v14l11-7z\" fill=\"white\"/>" | |
| : "<path d=\"M6 4h4v16H6zM14 4h4v16h-4z\" fill=\"white\"/>"; | |
| } | |
| video.addEventListener("play", updatePlayIcon); | |
| video.addEventListener("pause", updatePlayIcon); | |
| function seek(s) { video.currentTime = Math.max(0, video.currentTime+s); } | |
| function chStep(d) { if(channels.length) loadCh((curIdx+d+channels.length)%channels.length); } | |
| function toggleMute() { | |
| muted = !muted; video.muted = muted; | |
| muteBtn.classList.toggle("off", !muted); | |
| muteIco.innerHTML = muted | |
| ? "<path d=\"M11 5L6 9H2v6h4l5 4V5z\" fill=\"#f0804a\"/><path d=\"M23 9l-6 6M17 9l6 6\" fill=\"none\" stroke=\"#f0804a\" stroke-width=\"2\" stroke-linecap=\"round\"/>" | |
| : "<path d=\"M11 5L6 9H2v6h4l5 4V5z\" fill=\"#636366\"/><path d=\"M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07\" fill=\"none\" stroke=\"#636366\" stroke-width=\"2\" stroke-linecap=\"round\"/>"; | |
| } | |
| function toggleSub() { | |
| subOn = !subOn; subBtn.classList.toggle("off", !subOn); | |
| for(const t of video.textTracks) t.mode = subOn?"showing":"hidden"; | |
| showToast(subOn?"Untertitel ein":"Untertitel aus"); | |
| } | |
| const fsOverlay = document.getElementById("fs-overlay"); | |
| const rotateWarning = document.getElementById("rotate-warning"); | |
| const videoWrap = document.getElementById("video-wrap"); | |
| function openFS() { | |
| if (!channels[curIdx]) return; | |
| fsOverlay.insertBefore(video, fsOverlay.firstChild); | |
| fsOverlay.classList.add("active"); | |
| document.body.classList.add("fs-active"); | |
| document.body.style.overflow = "hidden"; | |
| rotateWarning.style.display = "none"; | |
| document.getElementById("fs-btn").classList.remove("off"); | |
| for (const t of video.textTracks) t.mode = "hidden"; | |
| if (screen.orientation && screen.orientation.lock && window.innerWidth < 768) { | |
| screen.orientation.lock("landscape").catch(() => {}); | |
| } | |
| video.play().catch(()=>{}); | |
| } | |
| function closeFS() { | |
| videoWrap.insertBefore(video, videoWrap.firstChild); | |
| fsOverlay.classList.remove("active"); | |
| document.body.classList.remove("fs-active"); | |
| document.body.style.overflow = ""; | |
| document.getElementById("fs-btn").classList.add("off"); | |
| for (const t of video.textTracks) t.mode = subOn ? "showing" : "hidden"; | |
| if (screen.orientation && screen.orientation.unlock && window.innerWidth < 768) { | |
| screen.orientation.unlock(); | |
| } | |
| updateRotateWarning(); | |
| video.play().catch(()=>{}); | |
| } | |
| function isPhone() { | |
| return Math.min(screen.width, screen.height) < 768; | |
| } | |
| function updateRotateWarning() { | |
| const landscape = window.innerWidth > window.innerHeight; | |
| const fsActive = fsOverlay.classList.contains("active"); | |
| rotateWarning.style.display = (isPhone() && landscape && !fsActive) ? "flex" : "none"; | |
| } | |
| window.addEventListener("resize", () => { updateRotateWarning(); scaleApp(); }); | |
| window.addEventListener("orientationchange", () => setTimeout(() => { updateRotateWarning(); scaleApp(); }, 100)); | |
| updateRotateWarning(); | |
| function scaleApp() { | |
| const scaler = document.getElementById("app-scaler"); | |
| if (window.innerWidth < 768) { | |
| scaler.style.transform = ""; | |
| scaler.style.padding = ""; | |
| scaler.style.background = ""; | |
| scaler.style.borderRadius = ""; | |
| scaler.style.boxShadow = ""; | |
| return; | |
| } | |
| const appW = 460 + 6; | |
| const appH = 720 + 6; | |
| const vw = window.innerWidth; | |
| const vh = window.innerHeight; | |
| const scale = Math.min((vw - 40) / appW, (vh - 40) / appH, 1.4); | |
| scaler.style.transform = `scale(${scale})`; | |
| } | |
| scaleApp(); | |
| const infoModal = document.getElementById("info-modal"); | |
| const infoBackdrop = document.getElementById("info-backdrop"); | |
| function openInfo() { | |
| infoModal.style.display = "block"; | |
| infoBackdrop.style.display = "block"; | |
| requestAnimationFrame(() => requestAnimationFrame(() => { | |
| infoModal.style.transform = "translateX(-50%) translateY(0)"; | |
| })); | |
| } | |
| function closeInfo() { | |
| infoModal.style.transform = "translateX(-50%) translateY(100%)"; | |
| setTimeout(() => { | |
| infoModal.style.display = "none"; | |
| infoBackdrop.style.display = "none"; | |
| }, 350); | |
| } | |
| function goFS() { openFS(); } | |
| function tapVideo() { | |
| overlay.classList.add("show"); | |
| clearTimeout(oTimer); | |
| oTimer = setTimeout(()=>overlay.classList.remove("show"), 3200); | |
| } | |
| function showToast(msg) { | |
| const t = document.getElementById("toast"); | |
| t.textContent = msg; t.classList.add("show"); | |
| setTimeout(()=>t.classList.remove("show"), 2800); | |
| } | |
| document.addEventListener("keydown", e => { | |
| const k = e.key.toLowerCase(); | |
| if (k==="arrowright"||k==="arrowdown") chStep(1); | |
| else if (k==="arrowleft"||k==="arrowup") chStep(-1); | |
| else if (k===" ") { e.preventDefault(); togglePlay(); } | |
| else if (k==="m") toggleMute(); | |
| else if (k==="u") toggleSub(); | |
| else if (k==="f") { | |
| if (!document.fullscreenElement) openFS(); | |
| else closeFS(); | |
| } | |
| }); | |
| video.addEventListener("loadedmetadata", () => { | |
| for (const t of video.textTracks) t.mode = subOn ? "showing" : "hidden"; | |
| }); | |
| video.textTracks.addEventListener("addtrack", () => { | |
| for (const t of video.textTracks) t.mode = subOn ? "showing" : "hidden"; | |
| }); | |
| (async()=>{ channels = await loadM3U(); buildBar(); if(channels.length) loadCh(0); })(); | |
| /* | |
| * Created by anb030.de – all rights reserved! | |
| * Copyright for the auraTiVi script belongs to A. Kleinod. | |
| * Version: 2.265 (20260313) | |
| * Lizenz: Creative Commons Attribution-NonCommercial 4.0 International (CC BY-NC 4.0) | |
| */ | |
| </script> | |
| </body> | |
| </html> |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
My m3u file as an example…
#EXTM3U
#EXTINF:-1 tvg-id="DasErste.de@HD" tvg-logo="img/ard.webp" tvg-language="German",ARD (Das Erste) HD [short:ARD] [lang:DE] [Geo-blocked] [quality:HD]
https://daserste-live.ard-mcdn.de/daserste/live/hls/de/master.m3u8
#EXTINF:-1 tvg-id="ZDF.de@HD" tvg-logo="img/zdf.webp" tvg-language="German",ZDF HD [short:ZDF] [lang:DE] [Geo-blocked] [quality:HD]
https://zdf-hls-15.akamaized.net/hls/live/2016498/de/high/master.m3u8
#EXTINF:-1 tvg-id="rbbFernsehen.de@Berlin" tvg-logo="img/rbb_bln.webp" tvg-language="German",RBB Berlin [short:RBB] [lang:DE] [Geo-blocked] [quality:HD]
https://rbb-hls-berlin.akamaized.net/hls/live/2017824/rbb_berlin/index.m3u8
#EXTINF:-1 tvg-id="ZDFinfo.de@HD" tvg-logo="img/zdf_info.webp" tvg-language="German",ZDFinfo HD [short:ZDFinfo] [lang:DE] [Geo-blocked] [quality:HD]
https://zdf-hls-17.akamaized.net/hls/live/2016500/de/veryhigh/master.m3u8
#EXTINF:-1 tvg-id="ZDFneo.de@HD" tvg-logo="img/zdf_neo.webp" tvg-language="German",ZDFneo HD [short:ZDFneo] [lang:DE] [Geo-blocked] [quality:HD]
https://zdf-hls-16.akamaized.net/hls/live/2016499/de/veryhigh/master.m3u8
#EXTINF:-1 tvg-id="ARDone.de@HD" tvg-logo="img/ard_one.webp" tvg-language="German",ARD One HD [short:ARD one] [lang:DE] [Geo-blocked] [quality:HD]
https://mcdn-one.ard.de/ardone/hls/master.m3u8
#EXTINF:-1 tvg-id="3sat.de@HD" tvg-logo="img/3sat.webp" tvg-language="German",3sat HD [short:3sat] [lang:DE] [Geo-blocked] [quality:HD]
https://zdf-hls-18.akamaized.net/hls/live/2016501/dach/high/master.m3u8
#EXTINF:-1 tvg-id="arte.de@HD" tvg-logo="img/arte.webp" tvg-language="German",arte HD [short:arte] [lang:DE] [Geo-blocked] [quality:HD]
https://artesimulcast.akamaized.net/hls/live/2030993/artelive_de/index.m3u8
#EXTINF:-1 tvg-id="WELT.de@HD" tvg-logo="img/welt.webp" tvg-language="German",WELT HD [short:WELT] [lang:DE] [Geo-blocked] [quality:HD]
https://w-live2weltcms.akamaized.net/hls/live/2041019/Welt-LivePGM/index.m3u8
#EXTINF:-1 tvg-id="tagesschau24.de@HD" tvg-logo="img/ts24.webp" tvg-language="German",Tagesschau 24 HD [short:TS24] [lang:DE] [Geo-blocked] [quality:HD]
https://tagesschau.akamaized.net/hls/live/2020115/tagesschau/tagesschau_1/master.m3u8
#EXTINF:-1 tvg-id="Nachrichten360.de@HD" tvg-logo="img/n_360.webp" tvg-language="German",Nachrichten 360 [short:N360] [lang:DE] [Geo-blocked] [quality:HD]
https://cdn-apse1-prod.tsv2.amagi.tv/linear/amg01821-lovetvfast-nachrichten360-samsungde/playlist.m3u8
#EXTINF:-1 tvg-id="phoenix.de@HD" tvg-logo="img/phoenix.webp" tvg-language="German",Phoenix HD [short:Phoenix] [lang:DE] [Geo-blocked] [quality:HD]
https://zdf-hls-19.akamaized.net/hls/live/2016502/de/high/master.m3u8
#EXTINF:-1 tvg-id="AlJazeera.qa@English" tvg-logo="img/aljazeera.webp" tvg-language="English", AlJazeera News [short:AlJazeera] [lang:EN] [Geo-blocked] [quality:SD]
https://dash4.antik.sk/live/test_aljazeera_eng/playlist.m3u8
#EXTINF:-1 tvg-id="bbc@HD" tvg-logo="img/bbc_engl.webp" tvg-language="English",BBC News HD [short:BBC] [lang:EN] [Geo-blocked] [quality:HD]
https://vs-hls-push-ww-live.akamaized.net/x=4/i=urn:bbc:pips:service:bbc_news_channel_hd/t=3840/v=pv14/b=5070016/main.m3u8
#EXTINF:-1 tvg-id="cnn@SD" tvg-logo="img/cnn_engl.webp" tvg-language="English",CNN [short:CNN] [lang:EN] [Geo-blocked] [quality:SD]
https://turnerlive.warnermediacdn.com/hls/live/586495/cnngo/cnn_slate/VIDEO_0_3564000.m3u8
#EXTINF:-1 tvg-id="DW.de@English" tvg-logo="img/dw_engl.webp" tvg-language="English",DW English HD [short:DW] [lang:EN] [Geo-blocked] [quality:HD]
https://dwamdstream102.akamaized.net/hls/live/2015525/dwstream102/index.m3u8
#EXTINF:-1 tvg-id="euronewsgerman.fr@DE" tvg-logo="img/euronews.webp" tvg-language="German",EuroNews Deutsch [short:EuroNews] [lang:DE] [Geo-blocked] [quality:SD]
https://575b7833.wurl.com/master/f36d25e7e52f1ba8d7e56eb859c636563214f541/UmxheHhUVi1ldV9FdXJvbmV3c0RldXRzY2hfSExT/playlist.m3u8
#EXTINF:-1 tvg-id="euronewsenglish.fr@EN" tvg-logo="img/euronews.webp" tvg-language="English",EuroNews English HD [short:EuroNews] [lang:EN] [Geo-blocked] [quality:HD]
https://dash4.antik.sk/live/test_euronews/playlist.m3u8
#EXTINF:-1 tvg-id="BRFernsehen.de@Nord" tvg-logo="img/br_no.webp" tvg-language="German",BR Fernsehen Nord HD [short:BR No] [lang:DE] [Geo-blocked] [quality:HD]
https://mcdn.br.de/br/fs/bfs_sued/hls/de/master.m3u8
#EXTINF:-1 tvg-id="hrfernsehen.de@SD" tvg-logo="img/hr.webp" tvg-language="German",hr-fernsehen [short:hr] [lang:DE] [Geo-blocked] [quality:SD]
https://hrhls.akamaized.net/hls/live/2024525/hrhls/index.m3u8
#EXTINF:-1 tvg-id="MDRFernsehen.de@Sachsen" tvg-logo="img/mdr_sa.webp" tvg-language="German",MDR Sachsen HD [short:MDR Sa] [lang:DE] [Geo-blocked] [quality:HD]
https://mdrtvsnhls.akamaized.net/hls/live/2016928/mdrtvsn/index.m3u8
#EXTINF:-1 tvg-id="NDRFernsehen.de@MecklenburgVorpommern" tvg-logo="img/ndr_mv.webp" tvg-language="German",NDR MV HD [short:NDR MV] [lang:DE] [Geo-blocked] [quality:HD]
https://mcdn.ndr.de/ndr/hls/ndr_fs/ndr_mv/master.m3u8
#EXTINF:-1 tvg-id="SRFernsehen.de@HD" tvg-logo="img/sr.webp" tvg-language="German",SR Fernsehen HD [short:SR] [lang:DE] [Geo-blocked] [quality:HD]
https://srfs.akamaized.net/hls/live/689649/srfsgeo/index.m3u8
#EXTINF:-1 tvg-id="SWRFernsehenBadenWurttemberg.de@HD" tvg-logo="img/swr_bw.webp" tvg-language="German",SWR BW HD [short:SWR BW] [lang:DE] [Geo-blocked] [quality:HD]
https://swrbwd-hls.akamaized.net/hls/live/2018672/swrbwd/master.m3u8
#EXTINF:-1 tvg-id="WDRFernsehen.de@Essen" tvg-logo="img/wdr_es.webp" tvg-language="German",WDR Essen HD [short:WDR Es] [lang:DE] [Geo-blocked] [quality:HD]
https://wdrlokalzeit.akamaized.net/hls/live/2018027-b/wdrlz_essen/master.m3u8
#EXTINF:-1 tvg-id="ARDalpha.de@HD" tvg-logo="img/ard_alpha.webp" tvg-language="German",ARD alpha HD [short:ARD α] [lang:DE] [Geo-blocked] [quality:HD]
https://mcdn.br.de/br/fs/ard_alpha/hls/de/master.m3u8
#EXTINF:-1 tvg-id="KiKA.de@HD" tvg-logo="img/kika.webp" tvg-language="German",KiKA HD [short:KiKA] [lang:DE] [Geo-blocked] [quality:HD]
https://kikageohls.akamaized.net/hls/live/2022693/livetvkika_de/master.m3u8
#EXTINF:-1 tvg-id="nickelodeon.de@SD" tvg-logo="img/nick.webp" tvg-language="German",Nickelodeon [short:NICK] [lang:DE] [Geo-blocked] [quality:SD]
https://ma.anixa.tv/clips/stream/nickelodeon/playlist.php