Kapsamlı teknik inceleme • Sorun tespiti • Çözüm önerileri
Anons sistemi belirtilen şarkı aralığında çalışmıyor. Asıl sebep: listenedDuration hesaplaması yanlış!
Sorun nedir?
Kurumsal müşteriler "10 şarkıda bir anons çalsın" diye ayarlıyor ama anons hiç çalmıyor.
Neden oluyor?
Sistem şarkının kaç saniye dinlendiğini yanlış hesaplıyor. Şarkı 3 dakika bile çalsa, sistem "0 saniye dinlendi" diye kaydediyor. 30 saniyenin altı sayılmadığı için sayaç hiç artmıyor.
Ne yapılmalı?
Dinleme süresini doğru hesaplayan kod kullanılmalı. Sistem zaten doğru hesaplama yapıyor (abuse tespiti için) ama anons için yanlış kod kullanılmış.
Dosya: player-core.js:2860
Hatalı kod:
const listenedDuration = this.currentTime || this.duration || 0;
Doğru hesaplama: trackSongEnd() fonksiyonundaki gibi totalListenedMs + playbackStartTime kullanılmalı.
public/themes/muzibu/js/player/
├── core/
│ ├── player-core.js (445KB - Ana logic)
│ └── safe-storage.js (localStorage güvenli erişim)
├── features/
│ ├── spot-player.js (⭐ ANONS SİSTEMİ)
│ ├── play-helpers.js (Genre/Playlist/Album çalma)
│ ├── session.js (Session yönetimi)
│ ├── api.js (API endpoint'leri)
│ ├── favorites.js (Favori işlemleri)
│ ├── device-profiler.js (Cihaz tespiti)
│ └── buffer-monitor.js (Buffer izleme)
└── lib/
└── hls.min.js (HLS.js v1.4.12)
Alpine.store('player') = {
currentSong: null,
queue: [],
queueIndex: 0,
isPlaying: false,
currentTime: 0,
duration: 0,
volume: 70,
// HLS
hls: null,
hlsCurrentLevel: 3,
// Kritik: Dinleme takibi
playbackStartTime: null,
totalListenedMs: 0,
currentPlayId: null,
// Spot guard
_isPlayingSpot: false
}
playSongFromQueue()
track-hit API
(play_count++)
onTrackEnded()
this.currentTime || this.duration || 0
MuzibuSpotPlayer.onSongListened(listenedDuration)
songsPlayed++
playNextSpot()
const listenedDuration = this.currentTime || this.duration || 0;
// SORUN:
// - this.currentTime şarkı bittiğinde 0 olabilir
// - Safari'de gapless geçişte sıfırlanıyor
// - undefined || undefined || 0 = 0
// - Sonuç: Her zaman 0 veya çok düşük değer
let listenedDuration = 0;
if (this.playbackStartTime) {
const currentSession = this.isPlaying
? (Date.now() - this.playbackStartTime) : 0;
listenedDuration = Math.floor(
(this.totalListenedMs + currentSession) / 1000
);
}
| ID | Şirket | Başlık | Audio |
|---|---|---|---|
| 2 | Macro Center | Homemade Kampanya | ✓ |
| 3 | Shell | Deli2go Anons | ✓ |
Toplam 2 aktif spot kaydı mevcut
| ID | Şirket | Aralık | Spot? |
|---|---|---|---|
| 28 | Blain Coffee | 10 | ✗ |
| 37 | LOTTA COFFEE | 1 | ✗ |
| 38 | Macro Center | 1 | ✓ |
| 39 | Shell | 1 | ✓ |
| 45 | Kırka Tatlıcısı | 5 | ✗ |
| 71 | WolfBull Gym | 1 | ✗ |
| 74 | RED EKSPRES | 2 | ✗ |
⚠️ 6 şirketin spot sistemi açık ama spot kaydı yok!
| Endpoint | Method | Amaç | Controller |
|---|---|---|---|
/api/spot/settings |
GET | Spot ayarları + aktif spot listesi | apiSpotSettings() |
/api/spot/next |
GET | Sıradaki spot (rotation) | apiNextSpot() |
/api/spot/play-start |
POST | Spot çalmaya başladı (log) | apiSpotPlayStart() |
/api/spot/play-end |
POST | Spot bitti (duration, skip) | apiSpotPlayEnd() |
/api/spot/toggle-pause |
POST | Şube için durdur/devam | apiSpotTogglePause() |
{
"enabled": true,
"songs_between": 10,
"corporate_id": 38,
"branch_id": 38,
"spot_is_paused": false,
"spot_settings_version": 12,
"spots": [
{
"id": 2,
"title": "Homemade Kampanya",
"url": "/storage/tenant1001/...", // ⚠️ JS'de audio_url bekleniyor!
"position": 1,
"duration": 12
}
]
}
# Audio Format (4 seviyeli öncelik)
MUZIBU_DEFAULT_AUDIO_FORMAT=mp3_auto
MUZIBU_AUDIO_FORCE= # Boş = kill switch kapalı
MUZIBU_HLS_TIMEOUT=2 # 2 saniye sonra MP3'e düş
# Soft Player (ABR kısıtlama)
MUZIBU_SOFT_PLAYER_VARIANTS=ultralow,low,mid
# Debug
PLAYER_DEBUG=0 # 0=Kapalı, 1=Root, 2=Herkes
# Session
MUZIBU_SESSION_POLLING=30000 # 30 saniye
MUZIBU_SESSION_TTL=7200 # 2 saat
# muzibu_corporate_accounts tablosu
spot_enabled = true/false # Sistem açık mı?
spot_songs_between = 10 # Kaç şarkıda bir
spot_current_index = 0 # Rotation sırası
spot_is_paused = false # Şube durduruldu mu?
spot_settings_version = 1 # Sync için versiyon
# JavaScript (localStorage)
muzibu_spot_counter = 0-10 # Şarkı sayacı
muzibu_spot_counter_settings # Settings hash
⚠️ .env'de anons ile ilgili değişken YOK. Tüm ayarlar veritabanında.
player-core.js satır 2860'daki kodu değiştir:
// ESKİ (YANLIŞ):
const listenedDuration = this.currentTime || this.duration || 0;
// YENİ (DOĞRU):
let listenedDuration = 0;
if (this.playbackStartTime) {
const currentSession = this.isPlaying
? (Date.now() - this.playbackStartTime) : 0;
listenedDuration = Math.floor(
(this.totalListenedMs + currentSession) / 1000
);
}
CorporateFrontController.php'de url yerine audio_url döndür:
// apiSpotSettings() içinde:
return [
'id' => $spot->id,
'title' => $spot->title,
'audio_url' => $spot->getAudioUrl(), // 'url' değil!
'position' => $spot->position,
'duration' => $spot->duration,
];
Geçici olarak console.log ekleyerek değerleri kontrol et:
// onTrackEnded() içinde:
console.log('🎙️ DEBUG:', {
currentTime: this.currentTime,
duration: this.duration,
playbackStartTime: this.playbackStartTime,
totalListenedMs: this.totalListenedMs,
calculatedDuration: listenedDuration
});
Admin panelde spot_enabled=1 ama spot kaydı olmayan şirketleri listele ve uyar.
MuzibuSpotPlayer.isEnabled() çalıştır → true dönmeli
MuzibuSpotPlayer.getSongsBetween() çalıştır → 1 dönmeli
🎙️ SpotPlayer: Song counted. Progress: 1/1
🎙️ SpotPlayer: Time for a spot! ve anons çalmalı
Şu an adım 5'te Song listened for Xs (< 30s, not counted) mesajı görülecek çünkü listenedDuration yanlış hesaplanıyor.
| Bileşen | Durum | Sorun | Aksiyon |
|---|---|---|---|
| listenedDuration Hesaplama | HATALI | currentTime || duration yanlış | Düzelt |
| API Response (audio_url) | UYUMSUZ | 'url' döndürülüyor, JS 'audio_url' bekliyor | Düzelt |
| spot-player.js | OK | - | - |
| Backend API | OK | - | - |
| Veritabanı Yapısı | OK | - | - |
| Aktif Spot Kaydı | KISITLI | Sadece 2 şirketin spotu var | Bilgilendirme |