⨯
Поиск
  • Услуги
  • Синглы
  • DJ-миксы
  • Deerror
  • Графический дизайн
  • Для Интернета
  • Фотографии
  • Анимация
  • Видео
  • Рубрики
  • Дайджест Tiku Digital
  • Подкаст Tiku Weekly
  • Архив
  • Главное
  • Резюме
  • Портфолио
  • Услуги
  • Музыка
  • Блог
  • Магазин
  • Напишите мне
  • Рубрики
  • Дайджест Tiku Digital
  • Подкаст Tiku Weekly
  • Веб-истории
  • Авторы
  • Тэги
  • Архив
WordPress × Wavesurfer JS

WordPress × Wavesurfer JS ★

 3  4.4 к  13 мин WordPress Веб‑разработка Программирование Разработка

Главное › Блог › WordPress × Wavesurfer JS

Автор: Тимофей Кузнецов Опубликовано: 2024-07-18 12:00 Обновлено: 2025-08-29 23:41 Факты проверены Оцените: ⭐ ⭐ ⭐ ⭐ ⭐ 3 Спасибо за оценку 😗 Оценка:


Содержание

  • WordPress × Wavesurfer JS: описание решения
  • WordPress × Wavesurfer JS: заключение

Поиск

Рубрики блога

  • Дизайн 225
  • Маркетинг 58
    • Интернет‑маркетинг 304
  • Музыка 132
  • Разработка 21
  • Распаковка 102
  • Все рубрики

WordPress × Wavesurfer JS – нако­нец-то дошли руки поде­лить­ся сво­им опы­том исполь­зо­ва­ния wavesurfer.js в связ­ке с сай­том на WordPress.

WordPress × Wavesurfer JS
WordPress × Wavesurfer JS
ВКонтакте логотип иконка

Под­пи­ши­тесь на Tiku Digital ВКонтакте

Когда я делал вто­рую вер­сию сво­е­го сай­та и решил обно­вить раз­дел с музы­кой мне захо­те­лось сде­лать пле­ер с визу­а­ли­за­ций частот­ной диа­грам­мы, как у SoundCloud. Я доста­точ­но быст­ро нашел wavesurfer.js и даль­ше начал­ся про­цесс сбо­ра инфор­ма­ции с раз­ных сай­тов о том как его исполь­зо­вать. Посте­пен­но я при­шел к жела­е­мо­му резуль­та­ту и решил им поде­лить­ся, воз­мож­но, это будет полез­но для таких же начи­на­ю­щих раз­ра­бот­чи­ков как и я.

Wavesurfer.js - это библиотека визуализации аудио с открытым исходным кодом для создания интерактивных, настраиваемых форм волны.

Я сде­лал шаб­лон стра­ни­цы WordPress, кото­рый мож­но выбрать при созда­нии стра­ни­цы и поме­стил в него сам скрипт, верст­ку и допол­ни­тель­ные воз­мож­но­сти, кото­рые мне были нужны.

Спи­сок опций, кото­рые есть в моём примере:

  • Аудио пле­ер в целом
  • Визу­а­ли­за­ция частот­ной диаграммы
  • Поиск по тре­ку (кли­ком по частот­ной диаграмме)
  • Вре­мя общее и про­шед­шее вре­мя трека
  • Изоб­ра­же­ние обложка
  • Кноп­ка play /​pause (икон­ка на кноп­ке меняется)
  • Регу­ля­тор громкости
  • Кноп­ка mute
  • Музы­каль­ные сти­ли в фор­ма­те тегов
  • Кноп­ка-ссыл­ка купить
  • Икон­ки-ссыл­ки на музы­каль­ные платформы
  • Опи­са­ние тре­ка и текст песни

Посмот­ри­те при­мер стра­ни­цы с пле­е­ром на моём сай­те в раз­де­ле музыка.

Пример страницы с плеером Wavesurfer JS
При­мер стра­ни­цы с пле­е­ром Wavesurfer JS

Далее я поста­ра­юсь подроб­но рас­ска­зать осо­бен­но­сти веб-раз­ра­бот­ки, кото­рую я сделал.

Вот исход­ный код шаб­ло­на стра­ни­цы WordPress с пле­е­ром Wavesurfer JS и допол­ни­тель­ны­ми функциями.

Сра­зу уточ­ню, что я исполь­зую вер­сию скрип­та wavesurfer.js 6.6.3 и раз­ме­щаю её локаль­но на сво­ём веб-сер­ве­ре. Это не послед­няя вер­сия, вы може­те най­ти её на GitHub проекта.

GitHub иконка логотип

Код мое­го реше­ния так­же досту­пен на GitHub

<?php
/* Template Name: Music - Single */
get_header();
get_sidebar();
?>



<div class="music-single-container">
	<div class="audio-player-container-wraper">
	<div class="audio-player-container">

		<div class="play-track-name">

    		<div id="playButton" class="play-button">
    			<img
    			id="playButtonIcon"
    			class="play-button-icon"
    			src="<?php echo get_template_directory_uri(); ?>/img/icons/play-thin.svg"
    			alt="Play Button"
    			/>
    		</div>
    		
    		<h1 class="track-name"><?php the_title(); ?></h1>
    		<p class="music-style post-category-main"><?php echo the_tags('',' ',''); ?></p>
			
		
		</div>

		<div id="waveform" class="waveform">
			<div id="loading_flag">
			  <!-- content set by JS  -->			
			</div>
		</div>

		<span id="currentTime">00:00:00</span>

		<span id="totalDuration">00:00:00</span>


		<div class="volume-group">
			<div class="volume-button">
				<img
				id="volumeIcon"
				class="volume-icon"
				src="<?php echo get_template_directory_uri(); ?>/img/icons/speaker-high-thin.svg"
				alt="Volume"
				/>
			</div>

			<input
			id="volumeSlider"
			class="volume-slider"
			type="range"
			name="volume-slider"
			min="0"
			max="100"
			value="50"
			aria-label="Volume"
			/>
		</div>
		
		<a data-lightbox="post-image" class="music-single-cover" href="<?php echo get_the_post_thumbnail_url( get_the_id(), 'full' ); ?>">
		<img src="<?php echo get_the_post_thumbnail_url( get_the_id(), 'medium' ); ?>" alt="<? the_title(); ?>" >
		</a>

	</div>
	</div>
	<div class="buy-streaming-wraper">
		<div class="buy-streaming-container">
			<div class="buy">
				<a class="wp-block-button__link wp-element-button" href="<?php echo get_post_meta($post->ID, '%mp3_Buy', true); ?>" target="_blank"><?php include'img/icons/buy-thin.php'; ?> 
                    <?php
                    $networksiteid = get_current_blog_id();
                    if( $networksiteid == 1 ){
                        echo "Купить";
                    } else {
            	        echo "Buy";
                    }
                    ?>
				</a>
			</div>
			<div class="streaming">
				<a class="streaming-link" id="streaming-link-vk-music" href="<?php echo get_post_meta($post->ID, '%VK_Music_link', true); ?>" target="_blank"><img decoding="async" src="https://tiku.ru/wp-content/uploads/2023/02/social-media-icons-svg-vk-music-01.svg" alt="VK Музыка иконка логотип" class="wp-image-6869"></a>

				<a class="streaming-link" id="streaming-link-ya-music" href="<?php echo get_post_meta($post->ID, '%Yandex_Music_link', true); ?>" target="_blank"><img decoding="async" src="https://tiku.ru/wp-content/uploads/2023/02/social-media-icons-svg-ya-music-01.svg" alt="Яндекс Музыка  иконка логотип" class="wp-image-6867"></a>
				
				<a class="streaming-link" id="streaming-link-promo-dj" href="<?php echo get_post_meta($post->ID, '%Promo_DJ_link', true); ?>" target="_blank"><img decoding="async" src="https://tiku.ru/wp-content/uploads/2023/05/social-media-icons-svg-promo-dj-01.svg" alt="PromoDJ иконка логотип" class="wp-image-6867"></a> 

				<a class="streaming-link" id="streaming-link-soundcloud" href="<?php echo get_post_meta($post->ID, '%Soundcloud_link', true); ?>" target="_blank"><img decoding="async" src="https://tiku.ru/wp-content/uploads/2023/02/social-media-icons-svg-soundcloud-01.svg" alt="Soundcloud иконка логотип" class="wp-image-6871"></a>

				<a class="streaming-link" id="streaming-link-bandcamp" href="<?php echo get_post_meta($post->ID, '%Bandcamp_link', true); ?>" target="_blank"><img decoding="async" src="https://tiku.ru/wp-content/uploads/2023/03/social-media-icons-svg-bandcamp-01.svg" alt="Bandcamp иконка логотип" class="wp-image-8002"></a>

				<a class="streaming-link" id="streaming-link-beatport" href="<?php echo get_post_meta($post->ID, '%Beatport_link', true); ?>" target="_blank"><img decoding="async" src="https://tiku.ru/wp-content/uploads/2023/03/social-media-icons-svg-beatport-01.svg" alt="Beatport иконка логотип" class="wp-image-8161"></a>

				<a class="streaming-link" id="streaming-link-apple-music" href="<?php echo get_post_meta($post->ID, '%Apple_Music_link', true); ?>" target="_blank"><img decoding="async" src="https://tiku.ru/wp-content/uploads/2023/02/social-media-icons-svg-apple-01.svg" alt="Apple Music иконка логотип" class="wp-image-7120"></a>

				<a class="streaming-link" id="streaming-link-spotify" href="<?php echo get_post_meta($post->ID, '%Spotify_link', true); ?>" target="_blank"><img decoding="async" src="https://tiku.ru/wp-content/uploads/2023/03/social-media-icons-svg-spotify-01.svg" alt="Spotify иконка логотип" class="wp-image-8010"></a>

				<a class="streaming-link" id="streaming-link-youtube" href="<?php echo get_post_meta($post->ID, '%YouTube_Music_link', true); ?>" target="_blank"><img decoding="async" src="https://tiku.ru/wp-content/uploads/2023/02/social-media-icons-svg-youtube-01.svg" alt="YouTube Music иконка логотип" class="wp-image-6842"></a>

				<a class="streaming-link" id="streaming-link-amazon" href="<?php echo get_post_meta($post->ID, '%Amazon_link', true); ?>" target="_blank"><img decoding="async" src="https://tiku.ru/wp-content/uploads/2023/03/social-media-icons-svg-amazon-music-01.svg" alt="Amazon Music иконка логотип" class="wp-image-8009"></a>

				<a class="streaming-link" id="streaming-link-deezer" href="<?php echo get_post_meta($post->ID, '%Deezer_link', true); ?>" target="_blank"><img decoding="async" src="https://tiku.ru/wp-content/uploads/2023/03/social-media-icons-svg-deezer-01.svg" alt="Deezer иконка логотип" class="wp-image-8008"></a>
			</div>
		</div>
	</div>

	
	<div class="music-single-desc">
		<p><?php include'template-parts/likes-views.php'; ?> </p>
		<?php the_content(); ?>
		<p class="work-year"><?php the_date('j F Y'); ?></p>

		<?php
		include'template-parts/share.php';
		include'template-parts/author.php';
		?>
		
		<p><?php include'template-parts/next-post.php'; ?></p>
		<p><?php include'template-parts/tags.php'; ?></p>
		
	</div>
	
</div>


<?php
    include'template-parts/similar-pages.php';

?>

<?php if ( comments_open() ) { ?>
<div class="page-container width-940">
	<div class="page-content-container">
		<div><?php comments_template(); ?></div>
	</div>
</div>
<?php } ?>

<?php
	get_footer();
?>


<?php
$musicfile = get_post_meta($post->ID, '%mp3_URL', true);
$pcm = get_post_meta($post->ID, '%pcm', true);
?>
	
<script src="<?php echo get_template_directory_uri(); ?>/js/wavesurfer.js"></script>
<script>

/* utiluty functions */

const playButton = document.querySelector("#playButton")
const playButtonIcon = document.querySelector("#playButtonIcon")
const waveform = document.querySelector("#waveform")
const volumeIcon = document.querySelector("#volumeIcon")
const volumeSlider = document.querySelector("#volumeSlider")
const currentTime = document.querySelector("#currentTime")
const totalDuration = document.querySelector("#totalDuration")
// --------------------------------------------------------- //
/**
 * Initialize Wavesurfer
 * @returns a new Wavesurfer instance
 */
const initializeWavesurfer = () => {
  return WaveSurfer.create({
	backend: "MediaElement",
    container: "#waveform",
    responsive: true,
    height: 80,
    waveColor: "#9999ff",
    progressColor: "#3300ff",
	barWidth: 2,
	barHeight: 1,
	barGap: 2,
	barRadius: 2,
  })
}



// --------------------------------------------------------- //
// Functions
/**
 * Toggle play button
 */
const togglePlay = () => {
  wavesurfer.playPause()
  const isPlaying = wavesurfer.isPlaying()
  if (isPlaying) {
    playButtonIcon.src = "https://tiku.ru/wp-content/themes/Tiku/img/icons/pause-thin.svg"
  } else {
    playButtonIcon.src = "https://tiku.ru/wp-content/themes/Tiku/img/icons/play-thin.svg"
  }
}
/**
 * Handles changing the volume slider input
 * @param {event} e
 */
const handleVolumeChange = e => {
  // Set volume as input value divided by 100
  // NB: Wavesurfer only excepts volume value between 0 - 1
  const volume = e.target.value / 100
  wavesurfer.setVolume(volume)
  // Save the value to local storage so it persists between page reloads
  localStorage.setItem("audio-player-volume", volume)
}
/**
 * Retrieves the volume value from local storage and sets the volume slider
 */
const setVolumeFromLocalStorage = () => {
  // Retrieves the volume from local storage, or falls back to default value of 50
  const volume = localStorage.getItem("audio-player-volume") * 100 || 50
  volumeSlider.value = volume
}
/**
 * Formats time as HH:MM:SS
 * @param {number} seconds
 * @returns time as HH:MM:SS
 */
const formatTimecode = seconds => {
  return new Date(seconds * 1000).toISOString().substr(11, 8)
}
/**
 * Toggles mute/unmute of the Wavesurfer volume
 * Also changes the volume icon and disables the volume slider
 */
const toggleMute = () => {
  wavesurfer.toggleMute()
  const isMuted = wavesurfer.getMute()
  if (isMuted) {
    volumeIcon.src = "https://tiku.ru/wp-content/themes/Tiku/img/icons/speaker-x-thin.svg"
    volumeSlider.disabled = true
  } else {
    volumeSlider.disabled = false
    volumeIcon.src = "https://tiku.ru/wp-content/themes/Tiku/img/icons/speaker-high-thin.svg"
  }
}
// --------------------------------------------------------- //
// Create a new instance and load the wavesurfer
	const wavesurfer = initializeWavesurfer()
	var musicFile = '<?php echo $musicfile; ?>'
	var pcm = <?php echo $pcm; ?>;
	wavesurfer.load(musicFile, pcm)
// --------------------------------------------------------- //
// Javascript Event listeners
window.addEventListener("load", setVolumeFromLocalStorage)
playButton.addEventListener("click", togglePlay)
volumeIcon.addEventListener("click", toggleMute)
volumeSlider.addEventListener("input", handleVolumeChange)
// --------------------------------------------------------- //
// Wavesurfer event listeners
wavesurfer.on("ready", () => {
  // Set wavesurfer volume
  wavesurfer.setVolume(volumeSlider.value / 100)
  // Set audio track total duration
  const duration = wavesurfer.getDuration()
  totalDuration.innerHTML = formatTimecode(duration)
})
// Sets the timecode current timestamp as audio plays
wavesurfer.on("audioprocess", () => {
  const time = wavesurfer.getCurrentTime()
  currentTime.innerHTML = formatTimecode(time)
})
// Resets the play button icon after audio ends
wavesurfer.on("finish", () => {
  playButtonIcon.src = "https://tiku.ru/wp-content/themes/Tiku/img/icons/play-thin.svg"
})


function UpdateLoadingFlag(Percentage) {
  if (document.getElementById("loading_flag")) {
  document.getElementById("loading_flag").innerText = "Загрузка " + Percentage + "%";
    if (Percentage >= 100) {1
      document.getElementById("loading_flag").style.display = "none";
    } else {
      document.getElementById("loading_flag").style.display = "block";
    }
  }
}
	

// show progress while loading sound
wavesurfer.on('loading', function(X, evt) {
  UpdateLoadingFlag(X);
});

// clean up etc., when wavesurfer fires the "ready" event
wavesurfer.on('ready', function() {
  console.log("ready fired");
});

document.getElementById("sun").onclick = function() {lightToDark()};

function lightToDark() {
  wavesurfer.setWaveColor('#ff9999');
  wavesurfer.setProgressColor('#ff6666');
}
document.getElementById("moon").onclick = function() {darkToLigh()};

function darkToLigh() {
  wavesurfer.setWaveColor('#9999ff');
  wavesurfer.setProgressColor('#3300ff');
}


if (document.getElementById("theme-link").href === "https://tiku.ru/wp-content/themes/Tiku/css/dark.css" || document.getElementById("theme-link").href === "https://tiku.ru/en/wp-content/themes/Tiku/css/dark.css") {
  wavesurfer.setWaveColor('#ff9999');
  wavesurfer.setProgressColor('#ff6666');
} else {
  wavesurfer.setWaveColor('#9999ff');
  wavesurfer.setProgressColor('#3300ff');
}



if(document.getElementById("streaming-link-amazon").getAttribute("href")!=="") {
	document.getElementById("streaming-link-amazon").style.display = "inline-block";
}
if(document.getElementById("streaming-link-vk-music").getAttribute("href")!=="") {
	document.getElementById("streaming-link-vk-music").style.display = "inline-block";
}
if(document.getElementById("streaming-link-ya-music").getAttribute("href")!=="") {
	document.getElementById("streaming-link-ya-music").style.display = "inline-block";
}
if(document.getElementById("streaming-link-soundcloud").getAttribute("href")!=="") {
	document.getElementById("streaming-link-soundcloud").style.display = "inline-block";
}
if(document.getElementById("streaming-link-bandcamp").getAttribute("href")!=="") {
	document.getElementById("streaming-link-bandcamp").style.display = "inline-block";
}
if(document.getElementById("streaming-link-beatport").getAttribute("href")!=="") {
	document.getElementById("streaming-link-beatport").style.display = "inline-block";
}
if(document.getElementById("streaming-link-apple-music").getAttribute("href")!=="") {
	document.getElementById("streaming-link-apple-music").style.display = "inline-block";
}
if(document.getElementById("streaming-link-spotify").getAttribute("href")!=="") {
	document.getElementById("streaming-link-spotify").style.display = "inline-block";
}
if(document.getElementById("streaming-link-youtube").getAttribute("href")!=="") {
	document.getElementById("streaming-link-youtube").style.display = "inline-block";
}
if(document.getElementById("streaming-link-deezer").getAttribute("href")!=="") {
	document.getElementById("streaming-link-deezer").style.display = "inline-block";
}
if(document.getElementById("streaming-link-promo-dj").getAttribute("href")!=="") {
	document.getElementById("streaming-link-promo-dj").style.display = "inline-block";
}

/*
wavesurfer.on('waveform-ready', () => {
	
	wavesurfer.exportPCM(1024, 10000, false);
	
})
*/

</script>

WordPress × Wavesurfer JS: описание решения

Далее я подроб­но поста­ра­юсь опи­сать состав­ные части решения.

Я актив­но исполь­зо­вал про­из­воль­ные поля WordPress, напри­мер что­бы полу­чить URL для .mp3 фай­ла или PCM дан­ные для постро­е­ния визу­а­ли­за­ции зву­ко­вой волны. 

В этой части кода созда­ют­ся пере­мен­ные в кото­рые запи­сы­ва­ют­ся дын­ные из про­из­воль­ных полей WordPress.

<?php
$musicfile = get_post_meta($post->ID, '%mp3_URL', true);
$pcm = get_post_meta($post->ID, '%pcm', true);
?>

Вот так это выгля­дит в админ­ке WordPress:

Произвольные поля WordPress

Вот этот блок кода настра­и­ва­ет сам wavesurfer, напри­мер то как будет выгля­деть визу­а­ли­за­ция волны:

const initializeWavesurfer = () => {
  return WaveSurfer.create({
    backend: "MediaElement",
    container: "#waveform",
    responsive: true,
    height: 80,
    waveColor: "#9999ff",
    progressColor: "#3300ff",
    barWidth: 2,
    barHeight: 1,
    barGap: 2,
    barRadius: 2,
  })
}

В этом бло­ке кода про­ис­хо­дит под­клю­че­ние .mp3 фай­ла и PCM дан­ных для быст­ро­го рен­де­рин­га визу­а­ли­за­ции (об этом подроб­нее позже):

// --------------------------------------------------------- //
// Create a new instance and load the wavesurfer
	const wavesurfer = initializeWavesurfer()
	var musicFile = '<?php echo $musicfile; ?>'
	var pcm = <?php echo $pcm; ?>;
	wavesurfer.load(musicFile, pcm)

Далее важ­ный момент, кото­рый я доде­лал уже после пер­во­го запус­ка. Одной из про­блем было то, что визу­а­ли­за­ция зву­ко­вой вол­ны отоб­ра­жа­лась толь­ко после того как аудио файл пол­но­стью загру­зит­ся (вы може­те видеть в коде раз­мет­ку и скрипт инди­ка­ции загруз­ки). Часто это зани­ма­ло зна­чи­тель­ное вре­мя для музы­каль­ных тре­ков, а когда я решил раз­ме­стить так­же DJ-мик­сы, про­бле­ма ста­ла очень серьез­ной – дол­гая загрузка.

Я уже знал, что это мож­но решить зара­нее ука­зав PCM дан­ные, но не знал, как эти дан­ные полу­чить. В ито­ге вот этот кусок кода помо­га­ет это сделать:

/*
wavesurfer.on('waveform-ready', () => {
	
	wavesurfer.exportPCM(1024, 10000, false);
	
})
*/

Он заком­мен­ти­ро­ван т. к. тре­бу­ет­ся толь­ко при раз­ме­ще­нии ново­го тре­ка. Про­цесс немно­го кри­вой, но это под­хо­дит лич­но для меня:

Cна­ча­ла я отклю­чаю PCM дан­ные вот тут:

Было:

wavesurfer.load(musicFile, pcm)

Ста­ло:

wavesurfer.load(musicFile)

После это­го пле­ер начи­на­ет рабо­тать в режи­ме загруз­ки аудио для постро­е­ния визу­а­ли­за­ции зву­ко­вой вол­ны. Я так­же уби­раю помет­ки ком­мен­та­рия с это­го кода:

wavesurfer.on('waveform-ready', () => {
	
	wavesurfer.exportPCM(1024, 10000, false);
	
})

Запол­няю всю про­чую инфор­ма­цию, кото­рую тре­бу­ет шаб­лон и запус­каю пред­ва­ри­тель­ный про­смотр стра­ни­цы WordPress, начи­на­ет­ся инди­ка­ция загруз­ки тре­ка и после её завер­ше­ния авто­ма­ти­че­ски откры­ва­ет­ся новая вклад­ка бра­у­зе­ра в кото­рой и содер­жать­ся PCM данные.

Далее я про­сто копи­рую их и встав­ляю в про­из­воль­ное поле WordPress для этой стра­ни­цы. Даль­ше надо вер­нуть PCM дан­ные в коде:

wavesurfer.load(musicFile, pcm) 

И заком­мен­ти­ро­вать этот блок кода:

/*
wavesurfer.on('waveform-ready', () => {
	
	wavesurfer.exportPCM(1024, 10000, false);
	
})
*/

После это­го визу­а­ли­за­ция отоб­ра­жа­ет­ся моментально.

🍩

Поддержите мой сайт

Задо­на­тить автору

CSS-сти­ли выгля­дят вот так и по ним, я думаю, ком­мен­та­рии излиш­ни. Но если у вас воз­ник­нут вопро­сы, пожа­луй­ста, напи­ши­те в ком­мен­та­ри­ях, я поста­ра­юсь помочь.

/* Audio Player */

.music-single-container {

}
.music-single-desc {
	margin: 0 auto;
	max-width: 1600px;
	padding: 2%;
}

.audio-player-container {
 	display: grid;
	gap: 0;
	grid-template-areas:
	"play-track-name play-track-name volume-group cover"
	"wave wave wave cover"
	"currentTime currentTime totalDuration cover";
	grid-template-rows: repeat(3, auto);
	grid-template-columns: repeat(4, 1fr);
	column-gap:  2%;
	row-gap:  0;
	justify-items: stretch;
	align-items: start;
	justify-content: space-evenly;
	align-content: space-evenly;
	padding: 2%;
	margin: 0 auto;
	max-width: 1920px;
	background: linear-gradient(#eee, #fff);
}

.audio-player-container-wraper {
	background: linear-gradient(#eee, #fff);
}

.music-single-cover, .music-single-cover:hover {
	grid-area: cover;
	width: 100%;
	border: 0;
}

.music-single-cover img {
	width: 100%;
	height: auto;
	aspect-ratio: 1 / 1;
	box-shadow: var(--shadow-elevation-medium);
}

.play-track-name {
	grid-area: play-track-name;
	display: grid;
	gap: 0;
	grid-template-areas:
	"play-pause track-name"
	"play-pause track-name"
	"play-pause music-style";
	grid-template-rows: repeat(3, auto);
	grid-template-columns: 80px auto;
	column-gap:  2%;
	row-gap:  0;
	align-self : center;
}

.play-track-name h1, .play-track-name .music-style {
	margin: 8px 0;
	padding: 0;
	line-height: 1.3;
}

.track-name {
	grid-area: track-name;
	text-align: start;
	align-self : end;

}

.music-style {
	grid-area: music-style;
}

.play-button {
	grid-area: play-pause;
	align-self : center;	
	width: 80px;
	height: 80px;
	padding: 20px;
}


#loading_flag {
	padding: 25px 0;
	text-align: center;
	background: url(../img/icons/waveform-thin.svg) center center;
	color: var(--accent-color);
	font-weight: bold;
	display: none;
}

#waveform {
	height: 120px;
}

.play-button-icon, .volume-icon {
	width: 100%;
	height: auto;
	aspect-ratio: 1 / 1;
}

.play-button, .volume-button {
	background: var(--accent-color);
	line-height: 0;
	margin: 0;
	border-radius: 50%;
	cursor: pointer;
	transition: 0.2s linear;
}

.play-button:hover, .volume-button:hover {
	background: #3300cc;
	transform: scale(1.1);
}

.volume-group {
	grid-area: volume-group;
	display: grid;
	gap: 0;
	grid-template-areas:
	"volume-button volume-slider";
	grid-template-rows: repeat(1, auto);
	grid-template-columns: repeat(2, auto);
	column-gap:  20px;
	row-gap:  0;
	justify-items: stretch;
	align-items: start;
	justify-content: space-evenly;
	align-content: space-evenly;
	align-self : center;
	justify-self: end;
}

.volume-button {
	grid-area: volume-button;
	align-self : center;
	width: 40px;
	height: 40px;
	padding: 8px;
}

.volume-slider {
	grid-area: volume-slider;
	align-self : center;	
}
#currentTime {
	grid-area: currentTime;
	color: #999;
}

#totalDuration {
	grid-area: totalDuration;
	justify-self: end;
	color: #999;
}

#waveform {
	grid-area: wave;
	align-self : end;
	padding: 20px 0;
	border-radius: 8px;

}

wave{
	overflow-x: hidden!important;
	border: 0!important;
	cursor: pointer!important;
}

@media only screen and (max-width: 940px) {
	.audio-player-container {
		padding: 8vw 4vw;
		display: grid;
		gap: 0;
		grid-template-areas:
		"cover cover cover cover"
		"play-track-name play-track-name play-track-name play-track-name"
		"wave wave wave wave"
		"currentTime volume-group volume-group totalDuration";
		grid-template-rows: repeat(4, auto);
		grid-template-columns: repeat(4, 1fr);
		column-gap:  2%;
		row-gap:  2%;
		justify-items: stretch;
		align-items: start;
		justify-content: space-evenly;
		align-content: space-evenly;
	}

	#currentTime, #totalDuration {
		align-self : center;
		font-size: 0.8em;
	}

	.volume-group {
		column-gap: 2vw;
		justify-self: center;
		padding: 20px 0;
	}

	.music-single-desc {
		padding: 4%;
	}

	.play-track-name {
		column-gap:  2vw;
	}

	.play-track-name h1 {
		font-size: 1.2em;
	}

	#waveform {
	margin-left: -4vw;
	margin-right: -4vw;
	}

	.play-track-name .music-style {
		line-height: 1.9;
	}
}

/* Input Range */

input[type=range] {
  width: 100%;
  margin: 7.6px 0;
  background-color: transparent;
  -webkit-appearance: none;
}
input[type=range]:focus {
  outline: none;
}
input[type=range]::-webkit-slider-runnable-track {
  background: rgba(153, 153, 255, 0.78);
  border: 0;
  border-radius: 25px;
  width: 100%;
  height: 4.8px;
  cursor: pointer;
}
input[type=range]::-webkit-slider-thumb {
  margin-top: -7.6px;
  width: 20px;
  height: 20px;
  background: var(--accent-color);
  border: 0;
  border-radius: 11px;
  cursor: pointer;
  -webkit-appearance: none;
}
input[type=range]:focus::-webkit-slider-runnable-track {
  background: #9e9eff;
}
input[type=range]::-moz-range-track {
  background: rgba(153, 153, 255, 0.78);
  border: 0;
  border-radius: 25px;
  width: 100%;
  height: 4.8px;
  cursor: pointer;
}
input[type=range]::-moz-range-thumb {
  width: 20px;
  height: 20px;
  background: var(--accent-color);
  border: 0;
  border-radius: 11px;
  cursor: pointer;
}
input[type=range]::-ms-track {
  background: transparent;
  border-color: transparent;
  border-width: 8.5px 0;
  color: transparent;
  width: 100%;
  height: 4.8px;
  cursor: pointer;
}
input[type=range]::-ms-fill-lower {
  background: #9494ff;
  border: 0;
  border-radius: 50px;
}
input[type=range]::-ms-fill-upper {
  background: rgba(153, 153, 255, 0.78);
  border: 0;
  border-radius: 50px;
}
input[type=range]::-ms-thumb {
  width: 20px;
  height: 20px;
  background: var(--accent-color);
  border: 0;
  border-radius: 11px;
  cursor: pointer;
  margin-top: 0px;
  /*Needed to keep the Edge thumb centred*/
}
input[type=range]:focus::-ms-fill-lower {
  background: rgba(153, 153, 255, 0.78);
}
input[type=range]:focus::-ms-fill-upper {
  background: #9e9eff;
}
/*TODO: Use one of the selectors from https://stackoverflow.com/a/20541859/7077589 and figure out
how to remove the virtical space around the range input in IE*/
@supports (-ms-ime-align:auto) {
  /* Pre-Chromium Edge only styles, selector taken from hhttps://stackoverflow.com/a/32202953/7077589 */
  input[type=range] {
    margin: 0;
    /*Edge starts the margin from the thumb, not the track as other browsers do*/
  }
}

/* Input Range */
.buy-streaming-wraper {
	background: #f5f5f5;
}
.buy-streaming-container {
	margin: 0 auto;
	padding: 1vw 2vw;
	max-width: 1600px;
	display: grid;
	gap: 0;
	grid-template-areas:
	"buy streaming-link";
	grid-template-rows: repeat(1, auto);
	grid-template-columns: repeat(2, 1fr);
	column-gap:  20px;
	row-gap:  0;
	justify-items: stretch;
	align-items: start;
	justify-content: space-evenly;
	align-content: space-evenly;
}

.streaming {
	grid-area: streaming-link;
	line-height: 0;
	align-self : center;
}
.streaming-link {
	width: 28px;
	display: none;
	border: 0;
	filter:progid:DXImageTransform.Microsoft.Alpha(opacity=60);
	-moz-opacity: 0.60;
	-khtml-opacity: 0.60;
	/* opacity: 0.60; */
}
.streaming-link:after {
	content: ''!important;
}
.streaming-link:hover {
	border: 0;
}
.streaming-link img {
	width: 100%;
	height: auto;
	aspect-ratio: 1 / 1;
	line-height: 0;
}
.buy {
	grid-area: buy;
}
.buy svg {
	width: 22px;
	vertical-align: text-bottom;
}
.buy .button, .buy .wp-block-button__link {
	margin: 0;
}


@media only screen and (max-width: 940px) {
	.buy-streaming-container {
		margin: 0 auto;
		padding: 4vw;
		display: grid;
		gap: 0;
		grid-template-areas:
		"buy"
		"streaming-link";
		grid-template-rows: repeat(2, auto);
		grid-template-columns: repeat(1, 1fr);
		column-gap:  20px;
		row-gap:  4vw;
		justify-items: stretch;
		align-items: start;
		justify-content: space-evenly;
		align-content: space-evenly;
	}
	.buy .button, .buy .wp-block-button__link {
		width: 100%;
	}
	.streaming {
		justify-self: center;
	}
	.streaming-link {
		width: 28px;
	}
}
/* Audio Player */

WordPress × Wavesurfer JS: заключение

Наде­юсь эта ста­тья будет полез­на таким же начи­на­ю­щим раз­ра­бот­чи­кам как и я.

Если у вас воз­ник­ли какие-либо вопро­сы или пред­ло­же­ния по моей реа­ли­за­ции, пожа­луй­ста, напи­ши­те мне или оставь­те комментарий.


3
4.4 к
13 мин

 Автор

Тимофей Кузнецов

Тимофей Кузнецов

Digital‑маркетолог, дизайнер и веб‑разработчик. Магистр прикладной информатики.
VK Telegram Email

 Далее

Vtubing: виртуальные AI аватары

Авторы используют аватары, чтобы показывать свою реальную внешность.

Публикация в блоге

Метки

Wavesurfer WordPress Веб-разработка

 Похожие посты

8 июля 2025 Веб-мастер против конструктора: когда лучше обратиться к специалисту. Для запуска простого сайта достаточно конструктора. Одностраничник, промострани...

Веб-мастер против конструктора

Когда лучше обратиться к специалисту.

Веб‑разработка Интернет‑маркетинг

14
1.8 к
3 мин
★
2 июля 2025 WordPress Cookie предупреждение без плагина - это то, что вам нужно, чтобы соблюдать закон и не замедлять работу вашего сайта. Лично я пришёл к этому...

WordPress Cookie предупреждение без плагина

То, что вам нужно, чтобы соблюдать закон и не замедлять работу сайта.

WordPress Веб‑разработка

28
22.2 к
4 мин
★
13 мая 2025 WordPress: увеличение картинки по клику - теперь это встроенная функция, а не головная боль. Привет, друзья-владельцы сайтов! Сегодня я хочу рассказа...

WordPress: увеличение картинки по клику

Теперь это встроенная функция, а не головная боль.

WordPress Разработка

9
5.5 к
5 мин
★
18 ноября 2024 Калькулятор самогонщика: как не ошибиться в расчетах и получить идеальный напиток. Самогоноварение — это не только искусство, но и точная наука. 



...

Калькулятор самогонщика

Как не ошибиться в расчетах и получить идеальный напиток. Самогоноварение!

Lifestyle Веб‑разработка

6
2.5 к
6 мин
5 ноября 2024 Теги в WordPress: как сделать ваш сайт удобнее и привлекательнее. WordPress — это мощная платформа для создания сайтов с огромными возможностями наст...

Теги в WordPress: полезно и удобно

WordPress Веб‑разработка

7
4.5 к
5 мин
20 сентября 2024 Плагин Wordpress для внутренней перелинковки - сегодня я поделюсь одной интересной находкой, это CherryLink Pro.







Внутренняя перелинковка на мо...

Плагин Wordpress для внутренней перелинковки

WordPress Интернет‑маркетинг

9
5 к
5 мин
★
29 августа 2024 Ускорение страниц сайта на которых встроено VK Видео через iframe. Не самая популярная тема в прошлом, но сейчас времена меняются.









Ускорение...

Ускорение страниц с VK Видео

Улучшение показателей страниц сайта со встройкой VK Видео.

WordPress Веб‑разработка

19
7.2 к
8 мин
22 августа 2024 Micro SaaS: как малыши меняют игру в мире большого программного обеспечения.







Мир программного обеспечения постоянно эволюционирует, и одним из...

Micro SaaS: мал да удал

Digital Веб‑разработка

5
6 к
5 мин

 3 комментария 

  • Gravatar Ирина:
    25.10.2024 в 19:43

    Эти ново­вве­де­ния я оце­ни­ла на стра­ни­це. Сра­зу вид­но, что было сде­ла­но от души и есть чет­кое пони­ма­ние струк­ту­ры стра­ни­цы и готов­но­сти для чита­те­лей улуч­шить посе­ща­е­мость за счет при­вле­че­ния вни­ма­ния. Как-то так.

    Ответить

  • Gravatar Ирина:
    28.12.2024 в 00:58

    И как итог – полу­чи­лось вели­ко­леп­но. Экс­пе­ри­мент в сво­ем роде удал­ся, не мог­ло быть сомнений.

    Ответить

  • Gravatar Анна:
    05.01.2025 в 00:37

    Инте­рес­но, как роди­лась такая идея и как она в жизнь вопло­ти­лась, и ведь полу­чи­лось прав­да кра­си­во и манко.

    Ответить

Напишите комментарий Отмена

Ваш адрес эл. почты не будет опубликован.

Обязательные поля помечены красной звёздочкой *

А вы знали, что ваши комментарии для меня как сладкий мёд?

Политика по персональным данным

Подвал

Хлебные крошки

Главное › Блог › WordPress × Wavesurfer JS

Главные разделы

  • Главное
  • Резюме
  • Портфолио
  • Услуги
  • Музыка
  • Блог
  • Магазин

Портфолио

  • Избранные работы
  • Интернет-маркетинг
  • Все работы
  • Графический дизайн
  • Для Интернета
  • Фотографии
  • Анимация
  • Видео

Музыка

  • Избранная музыка
  • Вся музыка
  • Синглы
  • DJ-миксы
  • Deerror
  • Студия

Рубрики блога

  • Lifestyle 41
  • Tiku 6
  • Дизайн 225
  • Жизнь 28
  • Игры 20
  • Маркетинг 58
  • Музыка 132
  • Разработка 21
  • Распаковка 102
  • Технологии 51
  • Все рубрики ↬

О сайте

Tiku — персональный сайт Тимофея Кузнецова aka Tiku Digital, портфолио и услуги интернет‑маркетолога, дизайнера и веб‑разработчика. Блог про digital‑маркетинг, дизайн, веб‑разработку и музыку.


Напишите мне

Форма обратной связи

 @ttiikkuu

 tiku@tiku.ru

Конфиденциальность

 Персональные данные

 Cookies


Политики сайта

Политика проверки фактов

Редакционные принципы

Информация о собственности и финансировании

Практическая политика обратной связи

Политика исправлений

Политика этики

Политика разнообразия

Отчет о кадровом разнообразии

Блог

  • Рубрики
  • Дайджест Tiku Digital
  • Подкаст Tiku Weekly
  • Веб-истории
  • Авторы
  • Тэги
  • Архив

Я здесь давно

 Tiku 2007 ...

Анахронизмы

Карта сайта

Карта блога

Благодарности

Какашка

Вы долистали до самой какашки!

Продолжая использовать мой сайт вы соглашаетесь с условиями использования файлов cookie 🍪 и политикой в отношении обработки персональных данных.