Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.56/9: Рейтинг темы: голосов - 9, средняя оценка - 4.56
14 / 14 / 2
Регистрация: 04.09.2009
Сообщений: 46
1

Контроль прослушиваемых аудио файлов

07.09.2009, 15:36. Просмотров 1786. Ответов 8
Метки нет (Все метки)

Всем доброго времени суток. Меня интересует такая задача: необходимо написать программу, которая будет висеть в трее и следить за тем, какую музыку пользователь слушает в данный момент. Т.е. она будет вести лог:
05.09.2009 15:40:45 Avril Lavigne Girlfriend.mp3
и т.д.

Так вот сам вопрос: возможно ли как нибудь следить за тем что в данный момент подается на аудио выход, пользователь не должен знать о существовании такой программы. Надстройку над проигрывателями не предлагать, ибо возможно использование различных плееров.

Заранее спасибо.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
07.09.2009, 15:36
Ответы с готовыми решениями:

Конвертер аудио-файлов (*.OGG)
Здравствуйте! Понадобился простенький конвертер. MP3 -> OGG. На форуме примеров не нашел, причем не...

Конвертор аудио и видео файлов
Добрый день, решил написать програму для курсовой, которая ковертирует разные аудио и видео файлы в...

Открытие аудио-файлов из длл библиотеки
Есть приложение с формой и есть dll-ка с файлом ресурсов, в котором лежит wav файл. Как по клику...

Архивация данных с потерями аудио файлов
День добрый, прошу помочь. Ищу человека который бы смог написать программу. Тема архивация данных с...

8
83 / 75 / 13
Регистрация: 03.09.2009
Сообщений: 346
07.09.2009, 20:27 2
Не знаю что вы понимаете под аудиовыходом, ИМХО на аудио выход подается аналоговый сигнал. Незнаю можно ли как-то напрямую проследить проигравает ли какой нибудь кодек\программа что либо. Но вот например можно же как-то отследить ВСЕ вызываемые системой файлы. И отсортировать их по маске *.мп3.
0
304 / 157 / 11
Регистрация: 07.06.2009
Сообщений: 538
07.09.2009, 21:15 3
Цитата Сообщение от to4kin Посмотреть сообщение
Надстройку над проигрывателями не предлагать, ибо возможно использование различных плееров.
тогда никак.
зы и вообще тему в газен.
0
Почетный модератор
11088 / 4059 / 389
Регистрация: 12.06.2008
Сообщений: 11,777
07.09.2009, 21:27 4
Как-то плохо стыкуются
Цитата Сообщение от to4kin
которая будет висеть в трее
и
Цитата Сообщение от to4kin
пользователь не должен знать о существовании такой программы
Если всё же пользователь не должен знать, то это получается Spyware... тут такие вещи не обсуждаются.
0
14 / 14 / 2
Регистрация: 04.09.2009
Сообщений: 46
08.09.2009, 00:51  [ТС] 5
Это не Spyware, прошу прощения что не так выразился. Программа необходима для контроля Dj, точнее того, какую музыку он ставит (Dj использует ноутбук). Т.е. необходимо вести лог всех mp3 файлов, которые он проигрывает за вечер. Если есть идеи как это сделать - буду очень признателен, моя идея видимо полная ересь.
0
14 / 14 / 2
Регистрация: 04.09.2009
Сообщений: 46
10.09.2009, 12:11  [ТС] 6
Вообщем погуглив удалось реализовать самому. Программа реализована для 2х проигрываетелей: Windows Media Player и WinAmp. Позже добавлю еще Aimp. Смысл реализации в следующем:
Для Windows Media Player: тут в принципе оказалось все просто, в интернете нашел плагин wmpblogging, который информацию о текущей композиции пишет в реестр, дальше все тривиально.
Для Winamp: тут пришлось помучаться, но заимев SDK с сайта Winamp'a удалось программным путем сохранять текущей плейлист на диск и получать ID текущей композиции, далее работа с файлом - что тоже тривиально. Так же есть команда для получения информации сразу от Winamp'a, но проблема в том что это будет работать только в области видимости самого проигрывателя, т.е. сторонним приложениям получить данную информацию очень сложно (нужно работать с памятью). Поэтому было принято решение сделать все это через плейлист.

Если кому будут нужны исходники, то могу выложить их тут.
0
Комбайнёр
1585 / 683 / 77
Регистрация: 27.05.2008
Сообщений: 2,535
10.09.2009, 15:31 7
Выкладывайте!
0
14 / 14 / 2
Регистрация: 04.09.2009
Сообщений: 46
10.09.2009, 16:48  [ТС] 8
Вообщем вот код программы (старался сделать комментарии более понятными):
файл Program.cs
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
using System;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using Microsoft.Win32;
 
namespace ControlMusic
{
    class Program
    {
        //Расположения дефолтного плейлиста
        private const string Playlist = "D:\\Documents and Settings\\Admin\\Application Data\\Winamp\\winamp.m3u";
        //Номер предыдущей сохраненной композиции
        private static int _num;
        //Тип медиаплеера: 1 - Winamp, 2 - WindowsMediaPlayer
        private static int _mediaPlayer;
        //Файл для сохранения названия композиций
        private static string _saveData;
        //Название композиции
        private static string _songName;
        //Автор композиции
        private static string _author = "";
        //Title композиции
        private static string _title = "";
 
        static void Main()
        {
            //Получаем имя компьтера, т.к. название файла = имя компьютера
            GetComputerName();
 
            while (true)
            {
                //Получаем тип медиаплеера
                GetMediaPlayer();
 
                //В зависимости от типа медиаплеера запускаем функцию обработки
                if (_mediaPlayer == 1)
                    WinampStart();
 
                if (_mediaPlayer == 2)
                    WmpStart();
 
                Thread.Sleep(300000);
            }
        }
 
        private static void GetComputerName()
        {
            _saveData = Environment.MachineName + ".list";
        }
 
        private static void GetMediaPlayer()
        {
            //Для получения типа медиаплеера используем список текущих процессов
            var allProcess = Process.GetProcesses();
            _mediaPlayer = 0;
 
            foreach (var process in allProcess)
            {
                switch (process.ProcessName)
                {
                    case "winamp":
                        _mediaPlayer = 1;
                        break;
                    case "wmplayer":
                        _mediaPlayer = 2;
                        break;
                }
            }
        }
 
        //Функция для работы с WindowsMediaPlayer'ом
        private static void WmpStart()
        {
            //Цикл работает, пока запущен проигрыватель
            while (Process.GetProcessesByName("wmplayer").Length != 0)
            {
                //Получаем название композиции
                WmpGetSong();
                //Пишем композицию в файл
                WriteData();
 
                Thread.Sleep(60000);
            }
        }
 
        private static void WmpGetSong()
        {
            //Читаем название композиции из реестра
            var readKey = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\MediaPlayer\\CurrentMetadata");
            if (readKey != null)
            {
                var author = (string)readKey.GetValue("Author");
                var title = (string)readKey.GetValue("Title");
 
                //Если предыдущая композиция отличается от текущей
                if (author.CompareTo(_author) != 0 || title.CompareTo(_title) != 0)
                {
                    //запоминаем информацию о новой композиции
                    _author = author;
                    _title = title;
                    _songName = author + " - " + title;
                }
                readKey.Close();
            }
        }
 
        //Функция для работы с Winamp'ом
        private static void WinampStart()
        {
            //Цикл работает, пока запущен проигрыватель
            while (Process.GetProcessesByName("winamp").Length != 0)
            {
                //Если удалось получить название композиции
                if (WinampGetSong())
                {
                    //пишем ее в файл
                    WriteData();
                }
 
                Thread.Sleep(60000);
            }
        }
 
        private static bool WinampGetSong()
        {
            try
            {
                var win = new WinampControl();
                //Получаем ID текущей композиции
                var num = win.GetTrackId();
 
                //Если текущая композиция отличается от предыдущей
                if (num.CompareTo(_num) == 0) return false;
                //запоминаем текущую композицию
                _num = num;
 
                //Сохраняем текущий плейлист
                win.SavePlaylist();
                //Делаем паузу в 1сек, даем возможность плейлисту корректно сохраниться
                Thread.Sleep(1000);
                //Работаем с плейлистом
                var reading = new StreamReader(Playlist, Encoding.Default);
                var songs = reading.ReadToEnd();
                //Выдергиваем из плейлиста название текущей композиции, еще можно получить место
                //расположения файла, для этого [0] нужно заменить на [1]
                _songName = Regex.Split(Regex.Split(songs, @".*\d\,")[_num + 1], @"\r\n")[0];
 
                reading.Close();
 
                return true;
            }
            catch
            {
                //Если словили ошибку - значит Winamp был закрыт, либо не удалось прочитать файл 
                //Эту секцию надо доработать
                _num = -1;
                return false;
            }
        }
 
        private static void WriteData()
        {
            var writing = new StreamWriter(_saveData, true);
            writing.WriteLine(DateTime.Now + ";" + _songName + ";");
            writing.Close();
        }
    }
}
файл WinampControl.cs

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
using System;
using System.Runtime.InteropServices;
 
namespace ControlMusic
{
    class WinampControl
    {
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
 
        public static extern IntPtr FindWindow
            (
            [MarshalAs(UnmanagedType.LPTStr)] string lpClassName,
            [MarshalAs(UnmanagedType.LPTStr)] string lpWindowName
            );
 
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
 
        static extern int SendMessageA(IntPtr hwnd, int wMsg, int wParam, uint lParam);
        private const string MWindowName = "Winamp v1.x";
 
        const int WmUser = 0x0400;
 
        //Посылаем команду для сохранения плейлиста
        public void SavePlaylist()
        {
            var hwnd = FindWindow(MWindowName, null);
            SendMessageA(hwnd, WmUser, 0, 120);
        }
 
        //Команда для получения ID текущей композиции
        public int GetTrackId()
        {
            var hwnd = FindWindow(MWindowName, null);
            return SendMessageA(hwnd, WmUser, 0, 125);
        }
    }
}
Ее еще нужно немного доработать в плане работы с WindowsMediaPlayer'ом, т.к. сли у файла отсутствуют теги, то в реестре инфа меняется только у Title. Конечно чожно отбросить автора и писать только Title, но мы не выбираем легких путей =) Так же нужно доработать исключения при работе с Winamp. В остальном программа отлично работает, с ошибками не вываливается. Проверял в течении 2х часов. Единственный небольшой недостаток, это рост памяти, он не критичный, но хотелось бы чтобы его вообще не было.

Если у кого есть какие замечания или предложения - с радостью готов их выслушать. Особенно интересует вопрос по "сбору мусора".
0
14 / 14 / 2
Регистрация: 04.09.2009
Сообщений: 46
17.09.2009, 16:22  [ТС] 9
Доделал программу полностью. Теперь она учитывает 3 проигрывателя (Winamp, Aimp, Windows Media Player), причем если запущены все 3 сразу, но музыка играет только с 1го, то это тоже будет учтено и при переключении между проигрывателями программа будет продолжать работать. Код программы был почти полностью переработан - теперь никакие файлы и никуда не пишутся, кроме, конечно, результирующего. Все что необходимо - это запустить программу, и удостовериться, что у пользователя есть доступ к папке Мои Документы =) После этого в этой папке будет создана поддиректория ControlMusic, куда и будет сохраняться файл с информацией.

Привожу новый код программы:

Program.cs
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
using System;
using System.IO;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
using Microsoft.Win32;
 
namespace ControlMusic
{
    class Program
    {
        //Директория для сохранения композиций
        private static readonly string SaveDir = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) +
                                         "\\ControlMusic\\";
        //Файл для сохранения названия композиций
        private static readonly string SaveData = SaveDir + Environment.MachineName + ".list";
 
        //Название композиции
        private static string _songName = "";
 
        static void Main()
        {
            //Проверка на доступность директории для записи
            while (!SetDir())
            {
                Thread.Sleep(300000);
            }
            
            //Записываем информацию в реестр, для авто запуска
            //WriteRegistryInfo();
 
            while (true)
            {
                //Если в данный момент играет Winamp/Aimp делаем вывод, что WMP остановлен
                //даже если он запущен. Winamp и Aimp имеют одинаковые названия окон,
                //поэтому если один из них играет, а другой приостановлен, то информация
                //считывается только с активного медиаплеера.
                if (!MediaStart("Winamp v1.x"))
                    MediaStart("WMPlayerApp");
 
                Thread.Sleep(60000);
            }
        }
 
        private static bool SetDir()
        {
            try
            {
                if (!Directory.Exists(SaveDir))
                    Directory.CreateDirectory(SaveDir);
                return true;
            }
            catch (Exception error)
            {
                MessageBox.Show(error.Message, "Ошибка создания директории", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }
        }
 
        private static void WriteRegistryInfo()
        {
            try
            {
                var myKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run\", true);
                if (myKey != null)
                {
                    if ((string)myKey.GetValue("ControlMusic") == null)
                        myKey.SetValue("ControlMusic", Application.ExecutablePath);
                }
            }
            catch (Exception error)
            {
                WriteData(error.Message);
            }
        }
 
        private static bool MediaStart(string window)
        {
 
            //Получаем название композиции
            var status = SetSongName(window);
            if (status.CompareTo("stop") != 0)
            {
                //Пишем композицию в файл
                if (status.CompareTo("new song") == 0)
                    WriteData(_songName);
 
                return true;
            }
 
            return false;
        }
 
        private static string SetSongName(string window)
        {
            var win = new WinampControl();
            var title = win.GetTitle(window);
            
            if (title == "Окно не найдено") return "stop";
            if (_songName.CompareTo(title) == 0) return "already saved";
            if (!CheckPlay(title)) return "stop";
 
            _songName = title;
            return "new song";
        }
 
        //Проверяем, играет ли музыка в Winamp и Aimp, либо он просто простаивает
        private static bool CheckPlay(string tittle)
        {
            var teg = new[] {"[Остановлено]", "[Приостановлено]", "[paused]", "[stopped]"};
            var tmp = Regex.Split(tittle, " ");
            var length = tmp.Length - 1;
            var play = true;
 
            for (var i = 0; i < teg.Length; i++)
            {
                if (teg[i] == tmp[length])
                    play = false;
            }
 
            return play;
        }
 
        //Пишем информацию в файл
        private static void WriteData(string writeData)
        {
            try
            {
                var writing = new StreamWriter(SaveData, true);
                writing.WriteLine(DateTime.Now + ";" + writeData + ";");
                writing.Close();
            }
            catch (Exception error)
            {
                MessageBox.Show(error.Message, "Ошибка записи в файл", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
    }
}
файл WinampControl.cs
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
 
namespace ControlMusic
{
    class WinampControl
    {
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr FindWindow
            (
            [MarshalAs(UnmanagedType.LPTStr)] string lpClassName,
            [MarshalAs(UnmanagedType.LPTStr)] string lpWindowName
            );
 
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern int GetWindowText(IntPtr hwnd, StringBuilder lpString, int maxSize);
 
        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        static extern int GetWindowTextLength(IntPtr hwnd);
 
        //Получаем title проигрываетля
        public string GetTitle(string mWindowName)
        {
            var hwnd = FindWindow(mWindowName, null);
            if (hwnd == IntPtr.Zero) return "Окно не найдено";
            
            var length = GetWindowTextLength(hwnd);
            var title = new StringBuilder(length + 1);
            
            GetWindowText(hwnd, title, title.Capacity);
            return title.ToString();
        }
    }
}
Надеюсь это кому-нибудь будет полезно =)
2
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
17.09.2009, 16:22

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Плеер, не активно переключение аудио/видео файлов
Приветствую, почему не активны кнопки переключения файлов в плеере? Свойства компонента обшарил,...

Вывод разных аудио файлов на разные аудиокарты
Имею компьютер с встроенной аудиокартой и внешней USBшной. Нужно что-бы была возможность выбрать...

[Qt] Получить список tcp соединений и прослушиваемых портов
Никак не могу найти, как получить список текущих подключений. Нужна такая же информация, как при...

Получить даты файлов за несколько дней и вывести в лог (контроль даты файлов)
Добрый день нужен батник следующего функционала: есть папка с 8-ю зип архивами (ежесуточный...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.