はじめに
音量ミキサーを作りたくなりました。こういうやつ。
できたのがこちらです。
しかもchatGPTにほとんどを書かせたので、全然調べてもないし1時間もせずにできました。
早速中身を見ていきましょう。
環境は
Windows8.1 VisualStudio2022 .NETCore7.0
1.プロセスIDと音量の取得
正規のWindows音量ミキサーを見てみると、アプリケーション名と現在の音量がスライダーで出てます。
これを再現するには、アプリケーション名と、音量を取得する必要がありそうです。さらに、アプリケーションはOS内ではプロセスIDというもので管理されてそうなので、これも取得したいですね。ということでコードを考えてもらいます。
ChatGPT、「オーディオを使用するプロセスのidと名前の一覧を取得するC#プログラムを教えて」
初めてGPTつかったけどマジですげえな、目の前でコード生えてくるの見ると感動してしまう。
//これ実行するとプロセスid,プロセス名,オーディオ音量をリストにして返してくれる
public List<Tuple<int, string, float>> GetAudioProcesses()
{
var audioProcesses = new List<Tuple<int, string, float>>();
var enumerator = new MMDeviceEnumerator();
var devices = enumerator.EnumerateAudioEndPoints(DataFlow.Render, DeviceState.Active);
foreach (var device in devices)
{
var sessions = device.AudioSessionManager.Sessions;
for (int i = 0; i < sessions.Count; i++)
{
var session = sessions[i];
var processId = session.GetProcessID;
if (processId != null)
{
var process = GetProcessFromId((int)processId);
if (process != null)
{
audioProcesses.Add(new Tuple<int, string, float>((int)processId, process.ProcessName, session.SimpleAudioVolume.Volume));
Debug.Print(session.SimpleAudioVolume.Volume.ToString());
}
}
}
}
return audioProcesses;
}
private Process GetProcessFromId(int processId)
{
try
{
return Process.GetProcessById(processId);
}
catch (ArgumentException)
{
// プロセスが存在しない場合はnullを返す
return null;
}
}
画面の実装
private void DisplayAudioProcesses()
{
// 既存のコントロールをクリアする
flowLayoutPanel.Controls.Clear();
audioProcesses = GetAudioProcesses();
// リストの内容を表示する
foreach (var audioProcess in audioProcesses)
{
// プロセスIDを表示するラベルを作成する
var idLabel = new Label
{
Text = $"Process ID: {audioProcess.Item1}",
AutoSize = true,
TextAlign = ContentAlignment.MiddleLeft
};
// プロセス名を表示するラベルを作成する
var nameLabel = new Label
{
Text = $"Process Name: {audioProcess.Item2}",
AutoSize = true,
TextAlign = ContentAlignment.MiddleLeft
};
// 音量を表示するラベルを作成する
var volumeLabel = new Label
{
Text = $"Volume: {(int)(audioProcess.Item3*100):F2}%",
AutoSize = true,
TextAlign = ContentAlignment.MiddleLeft
};
// 音量を設定するスライダーを作成する
var volumeSlider = new TrackBar
{
Minimum = 0,
Maximum = 100,
Value = (int)(audioProcess.Item3*100),
TickFrequency = 10,
Width = 150
};
volumeSlider.ValueChanged += VolumeSlider_ValueChanged;
Debug.Print("abya="+audioProcess.Item2 + ":" + audioProcess.Item3);
//volumeSlider.Value =(int)audioProcess.Item3 * 100;
// コントロールをパネルに追加する
var panel = new FlowLayoutPanel
{
FlowDirection = FlowDirection.LeftToRight,
Dock = DockStyle.Top,
Padding = new Padding(5),
Margin = new Padding(5),
Width = flowLayoutPanel.Width - 25,
Height = 60
};
panel.Controls.Add(idLabel);
panel.Controls.Add(nameLabel);
panel.Controls.Add(volumeLabel);
panel.Controls.Add(volumeSlider);
flowLayoutPanel.Controls.Add(panel);
}
}
private void VolumeSlider_ValueChanged(object sender, EventArgs e)
{
// スライダーの値が変更された時に、対応するプロセスの音量を変更する
var slider = sender as TrackBar;
var panel = slider.Parent as FlowLayoutPanel;
if (panel == null) return;
var volumeLabel = panel.Controls[2] as Label;
var index = flowLayoutPanel.Controls.GetChildIndex(panel);
audioProcesses[index] = new Tuple<int, string, float>(
audioProcesses[index].Item1,
audioProcesses[index].Item2,
slider.Value
);
Debug.Print(slider.Value.ToString());
SetApplicationVolume(audioProcesses[index].Item1, (float)slider.Value/100);
volumeLabel.Text = $"Volume: {slider.Value}%";
}
あとはこのプログラムを実行するためには、MainFormという名前のWindowsフォームを作成し、FlowLayoutPanelという名前のコントロールを配置しておく必要があります。また、リストの内容をaudioProcessesフィールドに設定し、MainForm_LoadメソッドでDisplayAudioProcessesメソッドを呼び出す必要があります。
の指示通り、コピペします。
もうできちゃった、すげえな。
頼んだ3行の表はできませんでしたが、まあいい感じに出来たので良しとしましょう。