WordPress, XenForo veya vBulletin gibi popüler içerik yönetim sistemlerinde sıklıkla karşılaştığımız "Bu konuyu/mesajı dinle" özelliği, kullanıcı deneyimini ve erişilebilirliği artıran son derece pratik bir fonksiyondur.
Harici yapay zeka seslendirme servislerinin yüksek abonelik ve API maliyetleri göz önüne alındığında, bu tür bir özelliği bütçesiz şekilde çözmek oldukça avantajlıdır. Bu rehberde, tarayıcıların yerel Web Speech API teknolojisini kullanarak MyBB forum sitenize özel, tamamen ücretsiz ve responsive (mobil uyumlu) bir Konu Seslendirme Modifikasyonu entegre etmeyi adım adım inceleyeceğiz.
Akıllı Metin Temizleme: Alıntıları (blockquote), kod bloklarını, imzaları, butonları ve görselleri atlayarak yalnızca asıl mesaj metnini seslendirir.
Türkçe Desteği: Sistemde yüklü olan tr-TR dil paketlerini önceliklendirir.
Kontrol Paneli: Oynat, duraklat, durdur ve okuma hızı (0.75x - 2x) seçenekleri sunar.
Mobil Uyumlu: CSS flex yapısı sayesinde tüm cihazlarda sorunsuz görünür.
Adım 1: CSS Stil Dosyasının Oluşturulması
İlk olarak oynatıcı panelinin tasarımını ve mobil uyumluluğunu sağlayacak CSS kodlarını ekliyoruz.
- Admin KP
Temalar ve Şablonlar yolunu izleyin.
- Kullandığınız temayı açıp CSS Oluştur butonuna tıklayın.
- Form alanlarını aşağıdaki gibi doldurun:
- Stil Adı: seslioku.css
- İlişkilendirilen: Genel Stil (Kendi içeriğimi yazmak istiyorum)
- Aşağıdaki kodları yapıştırıp kaydedin:
.tts-player {
margin: 15px 0;
padding: 14px;
background: #f5f5f5;
border: 1px solid #d7d7d7;
border-radius: 6px;
font-family: Arial, Helvetica, sans-serif;
}
.tts-title {
font-size: 17px;
font-weight: bold;
margin-bottom: 10px;
color: #333;
}
.tts-controls {
display: flex;
flex-wrap: wrap;
gap: 7px;
margin-bottom: 10px;
}
.tts-button {
border: 1px solid #cfcfcf;
background: #ffffff;
color: #333;
padding: 8px 13px;
border-radius: 4px;
cursor: pointer;
font-size: 13px;
transition: all 0.2s ease;
}
.tts-button:hover:not(:disabled) {
background: #eeeeee;
}
.tts-button:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.tts-settings {
display: flex;
align-items: center;
gap: 8px;
margin-top: 5px;
font-size: 13px;
}
#tts-speed {
padding: 5px 7px;
border: 1px solid #ccc;
border-radius: 4px;
background: #fff;
}
.tts-status {
margin-top: 10px;
font-size: 12px;
color: #666;
}
/* Mobil görünüm uyumluluğu */
@media (max-width: 600px) {
.tts-player {
padding: 12px;
}
.tts-controls {
width: 100%;
}
.tts-button {
flex: 1;
min-width: 80px;
padding: 9px 6px;
}
.tts-settings {
margin-top: 10px;
}
}- Admin KP
Temalar ve Şablonlar
Şablonlar sekmesine gidin.
- Kullandığınız temanın şablon grubunu genişletin ve Postbit Şablonları grubu altındaki postbit ile postbit_classic şablonlarını açın.
- Aşağıdaki kodu bulun:
{$post['message']}Şununla değiştirin ve kaydedin:
<div class="tts-post-content">
{$post['message']}
</div>- Admin KP
Şablonlar
Konu Gösterim Şablonları bölümünden showthread şablonunu açın.
- Sayfanın uygun bir yerine (tercihen sayfa sonundaki kodların üzerine) aşağıdaki JavaScript bloğunu ekleyin:
<script type="text/javascript">
(function() {
"use strict";
/* =====================================================
MYBB KONU SESLENDİRME MANTIĞI
===================================================== */
if (!("speechSynthesis" in window)) {
var unsupported = document.getElementById("tts-status");
if (unsupported) {
unsupported.textContent = "Tarayıcınız seslendirme özelliğini desteklemiyor.";
}
return;
}
var synth = window.speechSynthesis;
var playButton = document.getElementById("tts-play");
var pauseButton = document.getElementById("tts-pause");
var stopButton = document.getElementById("tts-stop");
var speedSelect = document.getElementById("tts-speed");
var statusBox = document.getElementById("tts-status");
var speechParts = [];
var currentPart = 0;
var stopped = true;
var currentUtterance = null;
function setStatus(message) {
if (statusBox) {
statusBox.textContent = message;
}
}
function getTurkishVoice() {
var voices = synth.getVoices();
if (!voices || voices.length === 0) return null;
var preferred = ["tr-TR", "tr"];
for (var p = 0; p < preferred.length; p++) {
for (var i = 0; i < voices.length; i++) {
var lang = (voices[i].lang || "").toLowerCase();
if (lang === preferred[p].toLowerCase()) {
return voices[i];
}
}
}
for (var j = 0; j < voices.length; j++) {
var language = (voices[j].lang || "").toLowerCase();
if (language.indexOf("tr") === 0) {
return voices[j];
}
}
return null;
}
function getPostContents() {
var posts = document.querySelectorAll(".tts-post-content");
var contents = [];
posts.forEach(function(post) {
var clone = post.cloneNode(true);
// Okunması istenmeyen elementlerin temizlenmesi
var removeSelectors = [
"blockquote", ".codeblock", ".signature",
".post_controls", ".postbit_controls", ".post_buttons",
"script", "style", "iframe", "button", "input",
"textarea", "select", "img"
];
removeSelectors.forEach(function(selector) {
clone.querySelectorAll(selector).forEach(function(element) {
element.remove();
});
});
clone.querySelectorAll('[class*="elfsight"]').forEach(function(element) {
element.remove();
});
var text = clone.innerText || clone.textContent || "";
text = text.replace(/\u00a0/g, " ").replace(/\s+/g, " ").trim();
if (text.length > 0) {
contents.push(text);
}
});
return contents;
}
function createSpeechParts() {
var contents = getPostContents();
speechParts = [];
contents.forEach(function(text) {
var sentences = text.match(/[^.!?]+[.!?]+|[^.!?]+$/g);
if (!sentences) sentences = [text];
var chunk = "";
sentences.forEach(function(sentence) {
sentence = sentence.trim();
if (!sentence) return;
if (chunk.length > 0 && chunk.length + sentence.length > 220) {
speechParts.push(chunk);
chunk = sentence;
} else {
if (chunk.length > 0) chunk += " ";
chunk += sentence;
}
});
if (chunk.length > 0) {
speechParts.push(chunk);
}
});
}
function speakCurrentPart() {
if (stopped) return;
if (currentPart >= speechParts.length) {
setStatus("Konu tamamlandı.");
playButton.disabled = false;
pauseButton.disabled = true;
stopButton.disabled = true;
currentPart = 0;
stopped = true;
return;
}
var text = speechParts[currentPart];
currentUtterance = new SpeechSynthesisUtterance(text);
currentUtterance.lang = "tr-TR";
currentUtterance.rate = parseFloat(speedSelect.value);
currentUtterance.pitch = 1;
currentUtterance.volume = 1;
var voice = getTurkishVoice();
if (voice) {
currentUtterance.voice = voice;
}
setStatus("Okunuyor... Bölüm " + (currentPart + 1) + " / " + speechParts.length);
currentUtterance.onend = function() {
if (!stopped) {
currentPart++;
setTimeout(speakCurrentPart, 80);
}
};
currentUtterance.onerror = function(event) {
if (stopped) return;
console.log("TTS hatası:", event);
setStatus("Seslendirme sırasında bir hata oluştu.");
playButton.disabled = false;
pauseButton.disabled = true;
stopButton.disabled = false;
};
synth.speak(currentUtterance);
}
playButton.addEventListener("click", function() {
if (speechParts.length === 0) {
createSpeechParts();
if (speechParts.length === 0) {
setStatus("Okunabilecek bir konu içeriği bulunamadı.");
return;
}
}
if (synth.paused) {
synth.resume();
stopped = false;
setStatus("Okuma devam ediyor...");
playButton.disabled = true;
pauseButton.disabled = false;
stopButton.disabled = false;
return;
}
if (!synth.speaking) {
stopped = false;
playButton.disabled = true;
pauseButton.disabled = false;
stopButton.disabled = false;
speakCurrentPart();
}
});
pauseButton.addEventListener("click", function() {
if (synth.speaking && !synth.paused) {
synth.pause();
setStatus("⏸ Okuma duraklatıldı.");
playButton.disabled = false;
pauseButton.disabled = true;
}
});
stopButton.addEventListener("click", function() {
stopped = true;
synth.cancel();
currentUtterance = null;
currentPart = 0;
setStatus("⏹ Okuma durduruldu.");
playButton.disabled = false;
pauseButton.disabled = true;
stopButton.disabled = true;
});
speedSelect.addEventListener("change", function() {
if (synth.speaking) {
synth.cancel();
stopped = false;
setTimeout(speakCurrentPart, 50);
}
});
if ("onvoiceschanged" in synth) {
synth.onvoiceschanged = function() {
getTurkishVoice();
};
}
setStatus("Hazır. Konuyu dinlemek için Oynat'a basın.");
})();
</script>- Yine showthread şablonu içerisinde kalın.
- Aşağıdaki kodu bulun:
{$posts}Hemen altına aşağıdaki HTML panel yapısını ekleyip şablonu kaydedin:
{$posts}
<div id="tts-player" class="tts-player" aria-label="Konu seslendirme paneli">
<div class="tts-title">
Konuyu Dinle
</div>
<div class="tts-controls">
<button type="button" id="tts-play" class="tts-button">
▶ Oynat
</button>
<button type="button" id="tts-pause" class="tts-button" disabled>
⏸ Duraklat
</button>
<button type="button" id="tts-stop" class="tts-button" disabled>
⏹ Durdur
</button>
</div>
<div class="tts-settings">
<label for="tts-speed">Okuma hızı:</label>
<select id="tts-speed">
<option value="0.75">0.75x</option>
<option value="1" selected>1x</option>
<option value="1.25">1.25x</option>
<option value="1.5">1.5x</option>
<option value="2">2x</option>
</select>
</div>
<div id="tts-status" class="tts-status">
Hazır. Konuyu dinlemek için Oynat'a basın.
</div>
</div>
|
Bu metnin taslağı yazar tarafından kaleme alınmış, dil bilgisi ve akıcılık düzenlemeleri Gemini iş birliğiyle tamamlanarak siz kıymetli okuyucularımızın beğenisine sunulmuştur. |
![]() DİKKAT |
MyBB İçin Ücretsiz Konu Seslendirme (Text-to-Speech) Modifikasyonu Nasıl Yapılır?

