В этой статье мы создадим простой консольный музыкальный плеер на языке программирования C. Плеер будет поддерживать воспроизведение файлов форматов .wav
, .mp3
и .flac
, а также базовое управление (воспроизведение, пауза, переключение треков и регулировка громкости). Мы будем использовать библиотеку miniaudio для работы со звуком.
Шаг 1: Подготовка системы
Перед началом работы убедитесь, что ваша система готова к разработке. Мы будем использовать Arch Linux, но инструкции можно адаптировать для других дистрибутивов.
Установка необходимых зависимостей
- Обновите систему:
sudo pacman -Syu
- Установите компилятор GCC и инструменты разработки:
sudo pacman -S gcc make
- Создайте каталог для проекта:
mkdir ~/music_playercd ~/music_player
Шаг 2: Скачивание и настройка библиотеки miniaudio
Библиотека miniaudio
— это легковесная библиотека для работы со звуком. Она не требует сложной установки, так как распространяется в виде одного заголовочного файла.
- Скачайте miniaudio: Перейдите на официальный репозиторий библиотеки: https://github.com/mackron/miniaudio
wget https://raw.githubusercontent.com/mackron/miniaudio/master/miniaudio.h
- Поместите
miniaudio.h
в каталог проекта: Убедитесь, что файл находится в том же каталоге, что и ваш исходный код.
Шаг 3: Написание кода
Создайте файл player.c
и скопируйте в него следующий код:
#include "miniaudio.h"
#include
#include
#include // Для strcmp, strrchr, strlen, strcpy
#include // Для opendir, readdir, closedir
#include // Для stat
#define MAX_TRACKS 1000
typedef struct {
char* tracks[MAX_TRACKS];
int track_count;
int current_track;
ma_engine engine;
} MusicPlayer;
// Реализация strdup
char* my_strdup(const char* str) {
if (str == NULL) return NULL;
size_t len = strlen(str) + 1; // Длина строки + нулевой символ
char* copy = malloc(len); // Выделяем память
if (copy == NULL) return NULL;
strcpy(copy, str); // Копируем строку
return copy;
}
void load_music_files_recursive(const char* directory, MusicPlayer* player) {
DIR* dir = opendir(directory);
if (!dir) {
perror("opendir");
return;
}
struct dirent* entry;
while ((entry = readdir(dir)) != NULL) {
// Пропускаем специальные директории "." и ".."
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
continue;
}
char full_path[1024];
snprintf(full_path, sizeof(full_path), "%s/%s", directory, entry->d_name);
struct stat st;
if (stat(full_path, &st) == -1) {
perror("stat");
continue;
}
if (S_ISDIR(st.st_mode)) {
// Это директория — обходим её рекурсивно
load_music_files_recursive(full_path, player);
} else if (S_ISREG(st.st_mode)) {
// Это файл — проверяем расширение
const char* ext = strrchr(entry->d_name, '.');
if (ext && (strcmp(ext, ".wav") == 0 || strcmp(ext, ".mp3") == 0 || strcmp(ext, ".flac") == 0)) {
if (player->track_count < MAX_TRACKS) {
player->tracks[player->track_count] = my_strdup(full_path); // Копируем путь
player->track_count++;
}
}
}
}
closedir(dir);
}
void load_music_files(const char* directory, MusicPlayer* player) {
load_music_files_recursive(directory, player);
if (player->track_count == 0) {
printf("No music files found in %s or its subdirectories.\n", directory);
} else {
printf("Loaded %d tracks from %s and its subdirectories.\n", player->track_count, directory);
}
}
void play_current_track(MusicPlayer* player) {
if (player->current_track < 0 || player->current_track >= player->track_count) {
printf("No tracks available.\n");
return;
}
ma_engine_stop(&player->engine);
ma_engine_uninit(&player->engine);
ma_result result = ma_engine_init(NULL, &player->engine);
if (result != MA_SUCCESS) {
printf("Failed to initialize audio engine.\n");
return;
}
printf("Playing: %s\n", player->tracks[player->current_track]);
ma_engine_play_sound(&player->engine, player->tracks[player->current_track], NULL);
}
void cleanup_player(MusicPlayer* player) {
for (int i = 0; i < player->track_count; i++) {
free(player->tracks[i]); // Освобождаем память для каждого пути
}
ma_engine_uninit(&player->engine);
}
int main() {
MusicPlayer player = {0};
player.current_track = 0;
// Загрузка файлов из каталога
load_music_files("/home/gratz/Музыка", &player);
if (player.track_count == 0) {
return -1;
}
// Инициализация движка
ma_result result = ma_engine_init(NULL, &player.engine);
if (result != MA_SUCCESS) {
printf("Failed to initialize audio engine.\n");
return -1;
}
// Основной цикл
char command[16];
while (1) {
printf("\nCommands: [play/pause] [next] [prev] [vol <0-1>] [quit]\n> ");
scanf("%s", command);
if (strcmp(command, "play") == 0 || strcmp(command, "pause") == 0) {
ma_engine_stop(&player.engine); // Пауза
play_current_track(&player); // Возобновление
} else if (strcmp(command, "next") == 0) {
player.current_track = (player.current_track + 1) % player.track_count;
play_current_track(&player);
} else if (strcmp(command, "prev") == 0) {
player.current_track = (player.current_track - 1 + player.track_count) % player.track_count;
play_current_track(&player);
} else if (strcmp(command, "vol") == 0) {
float volume;
scanf("%f", &volume);
if (volume < 0.0f) volume = 0.0f;
if (volume > 1.0f) volume = 1.0f;
ma_engine_set_volume(&player.engine, volume);
printf("Volume set to %.2f\n", volume);
} else if (strcmp(command, "quit") == 0) {
break;
} else {
printf("Unknown command.\n");
}
}
cleanup_player(&player);
return 0;
}
Шаг 4: Компиляция программы
- Скомпилируйте программу:
gcc player.c -o player -lpthread -lm -std=c99
- Проверьте, что файл
player
создан:ls -l player
Шаг 5: Настройка каталога с музыкой
- Выберите каталог с музыкой: Убедитесь, что в каталоге
/home/gratz/Музыка
находятся файлы форматов.wav
,.mp3
или.flac
. - Если каталог другой, измените путь в функции
load_music_files
:load_music_files("/путь/к/вашей/музыке", &player);
Шаг 6: Запуск программы
Запустите программу:
./player
Вы увидите список команд:
Commands: [play/pause] [next] [prev] [vol <0-1>] [quit]

Шаг 7: Использование
- Воспроизведите трек командой
play
. - Переключите треки командами
next
иprev
. - Измените громкость командой
vol 0.5
. - Завершите программу командой
quit
.
Заключение
Теперь вы знаете, как создать простой музыкальный плеер на языке C с использованием библиотеки miniaudio
. Этот проект можно расширять и улучшать, добавляя новые функции, такие как графический интерфейс, поддержка плейлистов или интеграция с сетевыми сервисами. Удачи в разработке!