1 #include "stdafx.h"
2 #include "FfmpegCore.h"
3
4 #include "AudioCommon.h"
5 #include "Common.h"
6 #include "MusicPlayer2.h"
7 #include "Player.h"
8
9 #define ft2ts(t) (((size_t)t.dwHighDateTime << 32) | (size_t)t.dwLowDateTime)
10
11 static std::wstring last_ffmpeg_core_error_cache;
12
CFfmpegCore()13 CFfmpegCore::CFfmpegCore() {
14 handle = nullptr;
15 err = 0;
16 Init(L"ffmpeg_core.dll");
17 if (!IsSucceed()) {
18 const wstring& info = theApp.m_str_table.LoadText(L"LOG_FFMPEG_INIT_FAILED");
19 theApp.WriteLog(info);
20 }
21 }
22
~CFfmpegCore()23 CFfmpegCore::~CFfmpegCore() {
24 if (handle || settings) UnInitCore();
25 CDllLib::UnInit();
26 }
27
InitCore()28 void CFfmpegCore::InitCore() {
29 if (IsSucceed()) {
30 CAudioCommon::m_surpported_format.clear();
31 CAudioCommon::m_all_surpported_extensions.clear();
32 CAudioCommon::m_surpported_format.push_back(CAudioCommon::CreateSupportedFormat(L"mp3 wma wav m4a ogg oga flac ape mp2 mp1 opus ape cda aif aiff cue mp4 mkv mka m2ts", theApp.m_str_table.LoadText(L"TXT_FILE_TYPE_BASE").c_str()));
33 CAudioCommon::m_surpported_format.push_back(CAudioCommon::CreateSupportedFormat(L"3gp 3g2 mj2 psp m4b ism ismv isma f4v", L"3gp"));
34 CAudioCommon::m_surpported_format.push_back(CAudioCommon::CreateSupportedFormat(L"aa", L"Audible Format 2, 3, and 4"));
35 CAudioCommon::m_surpported_format.push_back(CAudioCommon::CreateSupportedFormat(L"aac", L"AAC (Advanced Audio Coding)"));
36 CAudioCommon::m_surpported_format.push_back(CAudioCommon::CreateSupportedFormat(L"ac3", L"ATSC A/52A (AC-3)"));
37 CAudioCommon::m_surpported_format.push_back(CAudioCommon::CreateSupportedFormat(L"alac", L"ALAC (Apple Lossless Audio Codec)"));
38 CAudioCommon::m_surpported_format.push_back(CAudioCommon::CreateSupportedFormat(L"asf", L"Advanced Systems Format"));
39 CAudioCommon::m_surpported_format.push_back(CAudioCommon::CreateSupportedFormat(L"als", L"MPEG-4 Audio Lossless Coding (ALS)"));
40 CAudioCommon::m_surpported_format.push_back(CAudioCommon::CreateSupportedFormat(L"amr", L"AMR"));
41 CAudioCommon::m_surpported_format.push_back(CAudioCommon::CreateSupportedFormat(L"ape mac", L"Monkey's Audio"));
42 CAudioCommon::m_surpported_format.push_back(CAudioCommon::CreateSupportedFormat(L"aptx", L"aptX (Audio Processing Technology for Bluetooth)"));
43 CAudioCommon::m_surpported_format.push_back(CAudioCommon::CreateSupportedFormat(L"atrac", L"Adaptive TRansform Acoustic Coding"));
44 CAudioCommon::m_surpported_format.push_back(CAudioCommon::CreateSupportedFormat(L"dst", L"DST (Digital Stream Transfer)"));
45 CAudioCommon::m_surpported_format.push_back(CAudioCommon::CreateSupportedFormat(L"dca", L"DCA (DTS Coherent Acoustics)"));
46 CAudioCommon::m_surpported_format.push_back(CAudioCommon::CreateSupportedFormat(L"flac fla", L"FLAC (Free Lossless Audio Codec)"));
47 CAudioCommon::m_surpported_format.push_back(CAudioCommon::CreateSupportedFormat(L"flv live_flv kux", L"Adobe Flash Video"));
48 CAudioCommon::m_surpported_format.push_back(CAudioCommon::CreateSupportedFormat(L"gsm", L"GSM"));
49 CAudioCommon::m_surpported_format.push_back(CAudioCommon::CreateSupportedFormat(L"mp1 mp2 mp3 mp4", L"MPEG audio"));
50 CAudioCommon::m_surpported_format.push_back(CAudioCommon::CreateSupportedFormat(L"m4a mp4", L"MP4"));
51 CAudioCommon::m_surpported_format.push_back(CAudioCommon::CreateSupportedFormat(L"opus", L"Opus"));
52 CAudioCommon::m_surpported_format.push_back(CAudioCommon::CreateSupportedFormat(L"pcm", L"PCM"));
53 CAudioCommon::m_surpported_format.push_back(CAudioCommon::CreateSupportedFormat(L"spx", L"Speex"));
54 CAudioCommon::m_surpported_format.push_back(CAudioCommon::CreateSupportedFormat(L"tak", L"TAK (Tom's lossless Audio Kompressor)"));
55 CAudioCommon::m_surpported_format.push_back(CAudioCommon::CreateSupportedFormat(L"tta", L"TTA (True Audio)"));
56 CAudioCommon::m_surpported_format.push_back(CAudioCommon::CreateSupportedFormat(L"ogg oga", L"Vorbis"));
57 CAudioCommon::m_surpported_format.push_back(CAudioCommon::CreateSupportedFormat(L"wv", L"WavPack"));
58 CAudioCommon::m_surpported_format.push_back(CAudioCommon::CreateSupportedFormat(L"mpc mp+ mpp", L"Musepack"));
59 CAudioCommon::m_surpported_format.push_back(CAudioCommon::CreateSupportedFormat(L"wma", L"Windows Media Audio"));
60 CAudioCommon::m_surpported_format.push_back(CAudioCommon::CreateSupportedFormat(L"mov", L"mov"));
61 CAudioCommon::m_surpported_format.push_back(CAudioCommon::CreateSupportedFormat(L"avi", L"Audio Video Interleaved"));
62 CAudioCommon::m_surpported_format.push_back(CAudioCommon::CreateSupportedFormat(L"cda", L"CD Audio"));
63
64 if (!theApp.m_nc_setting_data.user_defined_type_ffmpeg.empty())
65 {
66 CAudioCommon::m_surpported_format.push_back(CAudioCommon::CreateSupportedFormat(theApp.m_nc_setting_data.user_defined_type_ffmpeg, theApp.m_str_table.LoadText(L"TXT_FILE_TYPE_FFMPEG_USER_DEFINE").c_str()));
67 }
68
69 for (const auto& item : CAudioCommon::m_surpported_format)
70 {
71 for (const auto& ext : item.extensions)
72 {
73 if (!ext.empty() && !CCommon::IsItemInVector(CAudioCommon::m_all_surpported_extensions, ext))
74 CAudioCommon::m_all_surpported_extensions.push_back(ext);
75 }
76 }
77
78 settings = ffmpeg_core_init_settings();
79 ffmpeg_core_log_set_flags(AV_LOG_SKIP_REPEATED | AV_LOG_PRINT_LEVEL);
80 ffmpeg_core_log_set_callback(LogCallback);
81 UpdateSettings();
82 auto devices = GetAudioDevices();
83 DeviceInfo d;
84 d.index = -1;
85 d.name = theApp.m_str_table.LoadText(L"TXT_OPT_PLAY_DEVICE_NAME_SDL_DEFAULT");
86 d.driver = L"";
87 d.flags = 0;
88 theApp.m_output_devices.clear();
89 theApp.m_output_devices.push_back(d);
90 int device_index = 0;
91 for (auto i = devices.begin(); i != devices.end(); i++) {
92 DeviceInfo d;
93 d.index = device_index++;
94 d.name = *i;
95 d.driver = L"";
96 d.flags = 0;
97 theApp.m_output_devices.push_back(d);
98 }
99 std::string ver("ffmpeg core version: ");
100 ver += ffmpeg_core_version_str();
101 ver += "\n";
102 OutputDebugStringA(ver.c_str());
103 ffmpeg_core_dump_library_version(1, AV_LOG_INFO);
104 ffmpeg_core_dump_ffmpeg_configuration(1, AV_LOG_INFO);
105 }
106 }
107
UnInitCore()108 void CFfmpegCore::UnInitCore() {
109 if (settings && IsSucceed()) {
110 free_ffmpeg_core_settings(settings);
111 settings = nullptr;
112 }
113 if (handle) {
114 Close();
115 }
116 }
117
GetAudioType()118 std::wstring CFfmpegCore::GetAudioType() {
119 return L"";
120 }
121
GetChannels()122 int CFfmpegCore::GetChannels() {
123 if (IsSucceed() && handle) {
124 return ffmpeg_core_get_channels(handle);
125 } else return 0;
126 }
127
GetFReq()128 int CFfmpegCore::GetFReq() {
129 if (IsSucceed() && handle) {
130 return ffmpeg_core_get_freq(handle);
131 } else return 0;
132 }
133
GetSoundFontName()134 std::wstring CFfmpegCore::GetSoundFontName() {
135 return L"";
136 }
137
Open(const wchar_t * file_path)138 void CFfmpegCore::Open(const wchar_t* file_path) {
139 if (!IsSucceed()) return;
140 if (handle) {
141 Close();
142 }
143 if (file_path) recent_file = file_path;
144 const wchar_t* device = nullptr;
145 if (theApp.m_play_setting_data.device_selected < static_cast<int>(theApp.m_output_devices.size()) && theApp.m_play_setting_data.device_selected) {
146 device = theApp.m_output_devices[theApp.m_play_setting_data.device_selected].name.c_str();
147 }
148 if (!settings) settings = ffmpeg_core_init_settings();
149 int re = ffmpeg_core_open3(file_path, &handle, settings, device);
150 if (re) {
151 err = re;
152 }
153 }
154
Close()155 void CFfmpegCore::Close() {
156 if (IsSucceed() && handle) {
157 free_music_handle(handle);
158 handle = nullptr;
159 err = 0;
160 }
161 }
162
Play()163 void CFfmpegCore::Play() {
164 if (!IsSucceed()) return;
165 if (!handle && !recent_file.empty()) {
166 Open(recent_file.c_str());
167 }
168 if (handle) {
169 ffmpeg_core_play(handle);
170 }
171 }
172
Pause()173 void CFfmpegCore::Pause() {
174 if (IsSucceed() && handle) {
175 ffmpeg_core_pause(handle);
176 }
177 }
178
Stop()179 void CFfmpegCore::Stop() {
180 Close();
181 }
182
SetVolume(int volume)183 void CFfmpegCore::SetVolume(int volume) {
184 if (!IsSucceed()) return;
185 if (handle) {
186 int re = ffmpeg_core_set_volume(handle, volume);
187 if (re) {
188 err = re;
189 }
190 } else {
191 ffmpeg_core_settings_set_volume(settings, volume);
192 }
193 }
194
SetSpeed(float speed)195 void CFfmpegCore::SetSpeed(float speed) {
196 if (!IsSucceed()) return;
197 if (handle) {
198 int re = ffmpeg_core_set_speed(handle, speed);
199 if (re) {
200 err = re;
201 }
202 } else {
203 ffmpeg_core_settings_set_speed(settings, speed);
204 }
205 }
206
SetPitch(int pitch)207 void CFfmpegCore::SetPitch(int pitch)
208 {
209 }
210
SongIsOver()211 bool CFfmpegCore::SongIsOver() {
212 if (IsSucceed() && handle) {
213 return ffmpeg_core_song_is_over(handle);
214 } else return false;
215 }
216
GetCurPosition()217 int CFfmpegCore::GetCurPosition() {
218 if (IsSucceed() && handle) {
219 return static_cast<int>(ffmpeg_core_get_cur_position(handle) / 1000);
220 } else return 0;
221 }
222
GetSongLength()223 int CFfmpegCore::GetSongLength() {
224 if (IsSucceed() && handle) {
225 int64_t length = ffmpeg_core_get_song_length(handle);
226 if (length != INT64_MIN)
227 return static_cast<int>(length / 1000);
228 else
229 return 0;
230 } else return 0;
231 }
232
SetCurPosition(int position)233 void CFfmpegCore::SetCurPosition(int position) {
234 if (IsSucceed() && handle && GetSongLength() != 0) { // 时长为0(获取失败)时seek(0)会卡死
235 int re = ffmpeg_core_seek(handle, (int64_t)position * 1000);
236 if (re) {
237 err = re;
238 }
239 }
240 }
241
GetAudioInfo(SongInfo & song_info,int flag)242 void CFfmpegCore::GetAudioInfo(SongInfo& song_info, int flag) {
243 if (!handle || !IsSucceed()) return;
244 if (flag & AF_LENGTH) song_info.end_pos.fromInt(GetSongLength());
245 if (flag & AF_CHANNEL_INFO) {
246 song_info.freq = ffmpeg_core_get_freq(handle);
247 song_info.bits = ffmpeg_core_get_bits(handle);
248 song_info.channels = ffmpeg_core_get_channels(handle);
249 }
250 if (flag & AF_BITRATE) {
251 song_info.bitrate = static_cast<short>(ffmpeg_core_get_bitrate(handle) / 1000);
252 }
253 if (flag & AF_TAG_INFO) {
254 CAudioTag audio_tag(song_info);
255 audio_tag.GetAudioRating();
256 if (!audio_tag.GetAudioTag()) //如果taglib获取信息失败,则使用ffmpeg获取标签信息
257 {
258 song_info.title = GetTitle();
259 song_info.artist = GetArtist();
260 song_info.album = GetAlbum();
261 song_info.comment = GetComment();
262 song_info.genre = GetGenre();
263 song_info.year = GetYear();
264 song_info.track = GetTrackNum();
265 }
266 }
267 }
268
GetAudioInfo(const wchar_t * file_path,SongInfo & song_info,int flag)269 void CFfmpegCore::GetAudioInfo(const wchar_t* file_path, SongInfo& song_info, int flag) {
270 if (!IsSucceed()) return;
271 MusicInfoHandle* h = nullptr;
272 int re = ffmpeg_core_info_open(file_path, &h);
273 if (re || !h) return;
274 if (flag & AF_LENGTH) {
275 int64_t length = ffmpeg_core_info_get_song_length(h);
276 if (length != INT64_MIN)
277 song_info.end_pos.fromInt(static_cast<int>(length / 1000));
278 else
279 song_info.end_pos.fromInt(0);
280 }
281 if (flag & AF_CHANNEL_INFO) {
282 song_info.freq = ffmpeg_core_info_get_freq(h);
283 song_info.bits = ffmpeg_core_info_get_bits(h);
284 song_info.channels = ffmpeg_core_info_get_channels(h);
285 }
286 if (flag & AF_BITRATE) {
287 song_info.bitrate = static_cast<short>(ffmpeg_core_info_get_bitrate(h) / 1000);
288 }
289 if (flag & AF_TAG_INFO) {
290 if (song_info.file_path.empty())
291 song_info.file_path = file_path;
292 CAudioTag audio_tag(song_info);
293 audio_tag.GetAudioRating();
294 if (!audio_tag.GetAudioTag()) //如果taglib获取信息失败,则使用ffmpeg获取标签信息
295 {
296 song_info.title = GetTitle(h);
297 song_info.artist = GetArtist(h);
298 song_info.album = GetAlbum(h);
299 song_info.comment = GetComment(h);
300 song_info.genre = GetGenre(h);
301 song_info.year = GetYear(h);
302 song_info.track = GetTrackNum(h);
303 }
304 }
305 free_music_info_handle(h);
306 }
307
IsMidi()308 bool CFfmpegCore::IsMidi() {
309 return false;
310 }
311
IsMidiConnotPlay()312 bool CFfmpegCore::IsMidiConnotPlay() {
313 return false;
314 }
315
GetMidiInfo()316 MidiInfo CFfmpegCore::GetMidiInfo() {
317 return MidiInfo();
318 }
319
GetMidiInnerLyric()320 std::wstring CFfmpegCore::GetMidiInnerLyric() {
321 return L"";
322 }
323
MidiNoLyric()324 bool CFfmpegCore::MidiNoLyric() {
325 return true;
326 }
327
GetPlayingState()328 PlayingState CFfmpegCore::GetPlayingState() {
329 if (IsSucceed() && handle) {
330 return ffmpeg_core_is_playing(handle) ? PlayingState::PS_PLAYING : PlayingState::PS_PAUSED;
331 } else return PlayingState::PS_STOPED;
332 }
333
ApplyEqualizer(int channel,int gain)334 void CFfmpegCore::ApplyEqualizer(int channel, int gain) {
335 if (!IsSucceed()) return;
336 channel = GetEqChannelFreq(channel);
337 if (handle) {
338 int re = ffmpeg_core_set_equalizer_channel(handle, channel, gain);
339 if (re) {
340 err = re;
341 }
342 } else {
343 ffmpeg_core_settings_set_equalizer_channel(settings, channel, gain);
344 }
345 }
346
SetReverb(int mix,int time)347 void CFfmpegCore::SetReverb(int mix, int time) {
348 }
349
ClearReverb()350 void CFfmpegCore::ClearReverb() {
351 }
352
GetFFTData(float fft_data[FFT_SAMPLE])353 void CFfmpegCore::GetFFTData(float fft_data[FFT_SAMPLE]) {
354 if (handle && IsSucceed()) {
355 memset(fft_data, 0, sizeof(fft_data));
356 ffmpeg_core_get_fft_data(handle, fft_data, FFT_SAMPLE);
357 } else {
358 memset(fft_data, 0, sizeof(fft_data));
359 }
360 }
361
GetErrorCode()362 int CFfmpegCore::GetErrorCode() {
363 if (err) {
364 int tmp = err;
365 err = 0;
366 return tmp;
367 }
368 // 不返回下层的错误,以免当下层重新打开文件时,即使这里返回0,上层依旧认为有错误
369 // if (handle) return ffmpeg_core_get_error(handle);
370 return 0;
371 }
372
GetErrorInfo(int error_code)373 std::wstring CFfmpegCore::GetErrorInfo(int error_code) {
374 if (error_code == 0 || !IsSucceed()) return L"";
375 auto tmp = ffmpeg_core_get_err_msg(error_code);
376 if (tmp) {
377 std::wstring re(tmp);
378 ffmpeg_core_free(tmp);
379 return re;
380 }
381 return L"";
382 }
383
GetErrorInfo()384 std::wstring CFfmpegCore::GetErrorInfo() {
385 return GetErrorInfo(GetErrorCode());
386 }
387
GetCoreType()388 PlayerCoreType CFfmpegCore::GetCoreType() {
389 return PlayerCoreType::PT_FFMPEG;
390 }
391
GetFunction()392 bool CFfmpegCore::GetFunction() {
393 bool rtn = true;
394 //获取函数入口
395 free_music_handle = (_free_music_handle)::GetProcAddress(m_dll_module, "free_music_handle");
396 free_music_info_handle = (_free_music_info_handle)::GetProcAddress(m_dll_module, "free_music_info_handle");
397 free_ffmpeg_core_settings = (_free_ffmpeg_core_settings)::GetProcAddress(m_dll_module, "free_ffmpeg_core_settings");
398 free_device_name_list = (_free_device_name_list)::GetProcAddress(m_dll_module, "free_device_name_list");
399 ffmpeg_core_free = (_ffmpeg_core_free)::GetProcAddress(m_dll_module, "ffmpeg_core_free");
400 ffmpeg_core_malloc = (_ffmpeg_core_malloc)::GetProcAddress(m_dll_module, "ffmpeg_core_malloc");
401 ffmpeg_core_realloc = (_ffmpeg_core_realloc)::GetProcAddress(m_dll_module, "ffmpeg_core_realloc");
402 ffmpeg_core_log_format_line = (_ffmpeg_core_log_format_line)::GetProcAddress(m_dll_module, "ffmpeg_core_log_format_line");
403 ffmpeg_core_log_set_callback = (_ffmpeg_core_log_set_callback)::GetProcAddress(m_dll_module, "ffmpeg_core_log_set_callback");
404 ffmpeg_core_log_set_flags = (_ffmpeg_core_log_set_flags)::GetProcAddress(m_dll_module, "ffmpeg_core_log_set_flags");
405 ffmpeg_core_version_str = (_ffmpeg_core_version_str)::GetProcAddress(m_dll_module, "ffmpeg_core_version_str");
406 ffmpeg_core_version = (_ffmpeg_core_version)::GetProcAddress(m_dll_module, "ffmpeg_core_version");
407 ffmpeg_core_dump_library_version = (_ffmpeg_core_dump_library_version)::GetProcAddress(m_dll_module, "ffmpeg_core_dump_library_version");
408 ffmpeg_core_dump_ffmpeg_configuration = (_ffmpeg_core_dump_ffmpeg_configuration)::GetProcAddress(m_dll_module, "ffmpeg_core_dump_ffmpeg_configuration");
409 ffmpeg_core_open = (_ffmpeg_core_open)::GetProcAddress(m_dll_module, "ffmpeg_core_open");
410 ffmpeg_core_open2 = (_ffmpeg_core_open2)::GetProcAddress(m_dll_module, "ffmpeg_core_open2");
411 ffmpeg_core_open3 = (_ffmpeg_core_open3)::GetProcAddress(m_dll_module, "ffmpeg_core_open3");
412 ffmpeg_core_info_open = (_ffmpeg_core_info_open)::GetProcAddress(m_dll_module, "ffmpeg_core_info_open");
413 ffmpeg_core_play = (_ffmpeg_core_play)::GetProcAddress(m_dll_module, "ffmpeg_core_play");
414 ffmpeg_core_pause = (_ffmpeg_core_pause)::GetProcAddress(m_dll_module, "ffmpeg_core_pause");
415 ffmpeg_core_seek = (_ffmpeg_core_seek)::GetProcAddress(m_dll_module, "ffmpeg_core_seek");
416 ffmpeg_core_set_volume = (_ffmpeg_core_set_volume)::GetProcAddress(m_dll_module, "ffmpeg_core_set_volume");
417 ffmpeg_core_set_speed = (_ffmpeg_core_set_speed)::GetProcAddress(m_dll_module, "ffmpeg_core_set_speed");
418 ffmpeg_core_set_equalizer_channel = (_ffmpeg_core_set_equalizer_channel)::GetProcAddress(m_dll_module, "ffmpeg_core_set_equalizer_channel");
419 ffmpeg_core_get_error = (_ffmpeg_core_get_error)::GetProcAddress(m_dll_module, "ffmpeg_core_get_error");
420 ffmpeg_core_get_err_msg = (_ffmpeg_core_get_err_msg)::GetProcAddress(m_dll_module, "ffmpeg_core_get_err_msg");
421 ffmpeg_core_get_err_msg2 = (_ffmpeg_core_get_err_msg2)::GetProcAddress(m_dll_module, "ffmpeg_core_get_err_msg2");
422 ffmpeg_core_get_cur_position = (_ffmpeg_core_get_cur_position)::GetProcAddress(m_dll_module, "ffmpeg_core_get_cur_position");
423 ffmpeg_core_song_is_over = (_ffmpeg_core_song_is_over)::GetProcAddress(m_dll_module, "ffmpeg_core_song_is_over");
424 ffmpeg_core_get_song_length = (_ffmpeg_core_get_song_length)::GetProcAddress(m_dll_module, "ffmpeg_core_get_song_length");
425 ffmpeg_core_info_get_song_length = (_ffmpeg_core_info_get_song_length)::GetProcAddress(m_dll_module, "ffmpeg_core_info_get_song_length");
426 ffmpeg_core_get_channels = (_ffmpeg_core_get_channels)::GetProcAddress(m_dll_module, "ffmpeg_core_get_channels");
427 ffmpeg_core_info_get_channels = (_ffmpeg_core_info_get_channels)::GetProcAddress(m_dll_module, "ffmpeg_core_info_get_channels");
428 ffmpeg_core_get_freq = (_ffmpeg_core_get_freq)::GetProcAddress(m_dll_module, "ffmpeg_core_get_freq");
429 ffmpeg_core_info_get_freq = (_ffmpeg_core_info_get_freq)::GetProcAddress(m_dll_module, "ffmpeg_core_info_get_freq");
430 ffmpeg_core_is_playing = (_ffmpeg_core_is_playing)::GetProcAddress(m_dll_module, "ffmpeg_core_is_playing");
431 ffmpeg_core_get_bits = (_ffmpeg_core_get_bits)::GetProcAddress(m_dll_module, "ffmpeg_core_get_bits");
432 ffmpeg_core_info_get_bits = (_ffmpeg_core_info_get_bits)::GetProcAddress(m_dll_module, "ffmpeg_core_info_get_bits");
433 ffmpeg_core_get_bitrate = (_ffmpeg_core_get_bitrate)::GetProcAddress(m_dll_module, "ffmpeg_core_get_bitrate");
434 ffmpeg_core_info_get_bitrate = (_ffmpeg_core_info_get_bitrate)::GetProcAddress(m_dll_module, "ffmpeg_core_info_get_bitrate");
435 ffmpeg_core_get_metadata = (_ffmpeg_core_get_metadata)::GetProcAddress(m_dll_module, "ffmpeg_core_get_metadata");
436 ffmpeg_core_info_get_metadata = (_ffmpeg_core_info_get_metadata)::GetProcAddress(m_dll_module, "ffmpeg_core_info_get_metadata");
437 ffmpeg_core_get_fft_data = (_ffmpeg_core_get_fft_data)::GetProcAddress(m_dll_module, "ffmpeg_core_get_fft_data");
438 ffmpeg_core_init_settings = (_ffmpeg_core_init_settings)::GetProcAddress(m_dll_module, "ffmpeg_core_init_settings");
439 ffmpeg_core_settings_set_volume = (_ffmpeg_core_settings_set_volume)::GetProcAddress(m_dll_module, "ffmpeg_core_settings_set_volume");
440 ffmpeg_core_settings_set_speed = (_ffmpeg_core_settings_set_speed)::GetProcAddress(m_dll_module, "ffmpeg_core_settings_set_speed");
441 ffmpeg_core_settings_set_cache_length = (_ffmpeg_core_settings_set_cache_length)::GetProcAddress(m_dll_module, "ffmpeg_core_settings_set_cache_length");
442 ffmpeg_core_settings_set_max_retry_count = (_ffmpeg_core_settings_set_max_retry_count)::GetProcAddress(m_dll_module, "ffmpeg_core_settings_set_max_retry_count");
443 ffmpeg_core_settings_set_url_retry_interval = (_ffmpeg_core_settings_set_url_retry_interval)::GetProcAddress(m_dll_module, "ffmpeg_core_settings_set_url_retry_interval");
444 ffmpeg_core_settings_set_equalizer_channel = (_ffmpeg_core_settings_set_equalizer_channel)::GetProcAddress(m_dll_module, "ffmpeg_core_settings_set_equalizer_channel");
445 ffmpeg_core_get_audio_devices = (_ffmpeg_core_get_audio_devices)::GetProcAddress(m_dll_module, "ffmpeg_core_get_audio_devices");
446 //判断是否成功
447 rtn &= (free_device_name_list != NULL);
448 rtn &= (free_music_handle != NULL);
449 rtn &= (free_music_info_handle != NULL);
450 rtn &= (free_ffmpeg_core_settings != NULL);
451 rtn &= (ffmpeg_core_free != NULL);
452 rtn &= (ffmpeg_core_malloc != NULL);
453 rtn &= (ffmpeg_core_realloc != NULL);
454 rtn &= (ffmpeg_core_log_format_line != NULL);
455 rtn &= (ffmpeg_core_log_set_callback != NULL);
456 rtn &= (ffmpeg_core_log_set_flags != NULL);
457 rtn &= (ffmpeg_core_version_str != NULL);
458 rtn &= (ffmpeg_core_version != NULL);
459 rtn &= (ffmpeg_core_dump_library_version != NULL);
460 rtn &= (ffmpeg_core_dump_ffmpeg_configuration != NULL);
461 rtn &= (ffmpeg_core_open != NULL);
462 rtn &= (ffmpeg_core_open2 != NULL);
463 rtn &= (ffmpeg_core_open3 != NULL);
464 rtn &= (ffmpeg_core_info_open != NULL);
465 rtn &= (ffmpeg_core_play != NULL);
466 rtn &= (ffmpeg_core_pause != NULL);
467 rtn &= (ffmpeg_core_seek != NULL);
468 rtn &= (ffmpeg_core_set_volume != NULL);
469 rtn &= (ffmpeg_core_set_speed != NULL);
470 rtn &= (ffmpeg_core_set_equalizer_channel != NULL);
471 rtn &= (ffmpeg_core_get_error != NULL);
472 rtn &= (ffmpeg_core_get_err_msg != NULL);
473 rtn &= (ffmpeg_core_get_err_msg2 != NULL);
474 rtn &= (ffmpeg_core_get_cur_position != NULL);
475 rtn &= (ffmpeg_core_song_is_over != NULL);
476 rtn &= (ffmpeg_core_get_song_length != NULL);
477 rtn &= (ffmpeg_core_info_get_song_length != NULL);
478 rtn &= (ffmpeg_core_get_channels != NULL);
479 rtn &= (ffmpeg_core_info_get_channels != NULL);
480 rtn &= (ffmpeg_core_get_freq != NULL);
481 rtn &= (ffmpeg_core_info_get_freq != NULL);
482 rtn &= (ffmpeg_core_is_playing != NULL);
483 rtn &= (ffmpeg_core_get_bits != NULL);
484 rtn &= (ffmpeg_core_info_get_bits != NULL);
485 rtn &= (ffmpeg_core_get_bitrate != NULL);
486 rtn &= (ffmpeg_core_info_get_bitrate != NULL);
487 rtn &= (ffmpeg_core_get_metadata != NULL);
488 rtn &= (ffmpeg_core_info_get_metadata != NULL);
489 rtn &= (ffmpeg_core_get_fft_data != NULL);
490 rtn &= (ffmpeg_core_init_settings != NULL);
491 rtn &= (ffmpeg_core_settings_set_volume != NULL);
492 rtn &= (ffmpeg_core_settings_set_speed != NULL);
493 rtn &= (ffmpeg_core_settings_set_cache_length != NULL);
494 rtn &= (ffmpeg_core_settings_set_max_retry_count != NULL);
495 rtn &= (ffmpeg_core_settings_set_url_retry_interval != NULL);
496 rtn &= (ffmpeg_core_settings_set_equalizer_channel != NULL);
497 rtn &= (ffmpeg_core_get_audio_devices != NULL);
498 if (ffmpeg_core_version) {
499 version = ffmpeg_core_version();
500 if (version > FFMPEG_CORE_VERSION(1, 0, 0, 0)) {
501 ffmpeg_core_is_wasapi_supported = (_ffmpeg_core_is_wasapi_supported)::GetProcAddress(m_dll_module, "ffmpeg_core_is_wasapi_supported");
502 ffmpeg_core_settings_set_use_WASAPI = (_ffmpeg_core_settings_set_use_WASAPI)::GetProcAddress(m_dll_module, "ffmpeg_core_settings_set_use_WASAPI");
503 ffmpeg_core_settings_set_enable_exclusive = (_ffmpeg_core_settings_set_enable_exclusive)::GetProcAddress(m_dll_module, "ffmpeg_core_settings_set_enable_exclusive");
504 ffmpeg_core_settings_set_max_wait_time = (_ffmpeg_core_settings_set_max_wait_time)::GetProcAddress(m_dll_module, "ffmpeg_core_settings_set_max_wait_time");
505 rtn &= (ffmpeg_core_is_wasapi_supported != NULL);
506 rtn &= (ffmpeg_core_settings_set_use_WASAPI != NULL);
507 rtn &= (ffmpeg_core_settings_set_enable_exclusive != NULL);
508 rtn &= (ffmpeg_core_settings_set_max_wait_time != NULL);
509 }
510 }
511 return rtn;
512 }
513
GetMetadata(std::string key,MusicInfoHandle * h)514 std::wstring CFfmpegCore::GetMetadata(std::string key, MusicInfoHandle* h) {
515 if (!IsSucceed()) return L"";
516 if (h) {
517 auto r = ffmpeg_core_info_get_metadata(h, key.c_str());
518 if (!r) return L"";
519 std::wstring re(r);
520 ffmpeg_core_free(r);
521 return re;
522 }
523 if (!handle) return L"";
524 auto r = ffmpeg_core_get_metadata(handle, key.c_str());
525 if (!r) return L"";
526 std::wstring re(r);
527 ffmpeg_core_free(r);
528 return re;
529 }
530
GetTitle(MusicInfoHandle * h)531 std::wstring CFfmpegCore::GetTitle(MusicInfoHandle* h) {
532 return GetMetadata("title", h);
533 }
534
GetArtist(MusicInfoHandle * h)535 std::wstring CFfmpegCore::GetArtist(MusicInfoHandle* h) {
536 return GetMetadata("artist", h);
537 }
538
GetAlbum(MusicInfoHandle * h)539 std::wstring CFfmpegCore::GetAlbum(MusicInfoHandle* h) {
540 return GetMetadata("album", h);
541 }
542
GetComment(MusicInfoHandle * h)543 std::wstring CFfmpegCore::GetComment(MusicInfoHandle* h) {
544 auto re = GetMetadata("comment", h);
545 if (!re.empty()) return re;
546 return GetMetadata("description", h);
547 }
548
GetGenre(MusicInfoHandle * h)549 std::wstring CFfmpegCore::GetGenre(MusicInfoHandle* h) {
550 return GetMetadata("genre", h);
551 }
552
GetDate(MusicInfoHandle * h)553 std::wstring CFfmpegCore::GetDate(MusicInfoHandle* h) {
554 return GetMetadata("date", h);
555 }
556
GetYear(MusicInfoHandle * h)557 unsigned short CFfmpegCore::GetYear(MusicInfoHandle* h) {
558 auto r = GetDate(h);
559 if (r.empty()) return 0;
560 unsigned short year = 0;
561 if (swscanf_s(r.c_str(), L"%hu", &year) == 1) return year;
562 return 0;
563 }
564
GetTrack(MusicInfoHandle * h)565 std::wstring CFfmpegCore::GetTrack(MusicInfoHandle* h) {
566 return GetMetadata("track", h);
567 }
568
GetTrackNum(MusicInfoHandle * h)569 int CFfmpegCore::GetTrackNum(MusicInfoHandle* h) {
570 auto r = GetTrack(h);
571 if (r.empty()) return 0;
572 int track;
573 if (swscanf_s(r.c_str(), L"%i", &track) == 1) return track;
574 return 0;
575 }
576
LogCallback(void * ptr,int level,const char * fmt,va_list vl)577 void CFfmpegCore::LogCallback(void* ptr, int level, const char* fmt, va_list vl) {
578 if (level > AV_LOG_VERBOSE) return;
579 CFfmpegCore* ffmpeg_core = dynamic_cast<CFfmpegCore*>(CPlayer::GetInstance().GetPlayerCore());
580 if (ffmpeg_core == nullptr)
581 return;
582 char buf[1024];
583 int print = 1;
584 int r = ffmpeg_core->ffmpeg_core_log_format_line(ptr, level, fmt, vl, buf, sizeof(buf), &print);
585 if (r > 0) {
586 std::wstring s = CCommon::StrToUnicode(std::string(buf, r), CodeType::UTF8);
587 if (s.find(L"Last message repeated") != -1) {
588 return;
589 }
590 OutputDebugStringW(s.c_str());
591 if (level <= AV_LOG_ERROR) {
592 if (s.back() == '\n') {
593 s.pop_back();
594 }
595 if (last_ffmpeg_core_error_cache.empty() || last_ffmpeg_core_error_cache != s) {
596 last_ffmpeg_core_error_cache = s;
597 theApp.WriteLog(s);
598 }
599 }
600 }
601 }
602
UpdateSettings()603 void CFfmpegCore::UpdateSettings() {
604 SetCacheLength(theApp.m_play_setting_data.ffmpeg_core_cache_length);
605 SetMaxRetryCount(theApp.m_play_setting_data.ffmpeg_core_max_retry_count);
606 SetUrlRetryInterval(theApp.m_play_setting_data.ffmpeg_core_url_retry_interval);
607 EnableWASAPI(theApp.m_play_setting_data.ffmpeg_core_enable_WASAPI);
608 EnableExclusiveMode(theApp.m_play_setting_data.ffmpeg_core_enable_WASAPI_exclusive_mode);
609 SetMaxWaitTime(theApp.m_play_setting_data.ffmpeg_core_max_wait_time);
610 }
611
SetCacheLength(int cache_length)612 void CFfmpegCore::SetCacheLength(int cache_length) {
613 if (settings && IsSucceed()) {
614 ffmpeg_core_settings_set_cache_length(settings, cache_length);
615 }
616 }
617
SetMaxRetryCount(int max_retry_count)618 void CFfmpegCore::SetMaxRetryCount(int max_retry_count) {
619 if (settings && IsSucceed()) {
620 ffmpeg_core_settings_set_max_retry_count(settings, max_retry_count);
621 }
622 }
623
SetUrlRetryInterval(int url_retry_interval)624 void CFfmpegCore::SetUrlRetryInterval(int url_retry_interval) {
625 if (settings && IsSucceed()) {
626 ffmpeg_core_settings_set_url_retry_interval(settings, url_retry_interval);
627 }
628 }
629
GetEqChannelFreq(int channel)630 int CFfmpegCore::GetEqChannelFreq(int channel) {
631 switch (channel) {
632 case 0:
633 return 80;
634 case 1:
635 return 125;
636 case 2:
637 return 250;
638 case 3:
639 return 500;
640 case 4:
641 return 1000;
642 case 5:
643 return 1500;
644 case 6:
645 return 2000;
646 case 7:
647 return 4000;
648 case 8:
649 return 8000;
650 case 9:
651 return 16000;
652 default:
653 return 0;
654 }
655 }
656
GetAudioDevices()657 std::list<std::wstring> CFfmpegCore::GetAudioDevices() {
658 if (!IsSucceed()) return {};
659 auto d = ffmpeg_core_get_audio_devices();
660 if (!d) return {};
661 std::list<std::wstring> l;
662 l.push_back(CCommon::StrToUnicode(d->device, CodeType::UTF8));
663 auto t = d;
664 while (t->next) {
665 t = t->next;
666 l.push_back(CCommon::StrToUnicode(t->device, CodeType::UTF8));
667 }
668 free_device_name_list(&d);
669 return l;
670 }
671
EncodeAudio(SongInfo song_info,const wstring & dest_file_path,EncodeFormat encode_format,void * encode_para,int dest_freq,EncodeAudioProc proc)672 bool CFfmpegCore::EncodeAudio(SongInfo song_info, const wstring& dest_file_path, EncodeFormat encode_format, void* encode_para, int dest_freq, EncodeAudioProc proc)
673 {
674 return false;
675 }
676
InitEncoder()677 bool CFfmpegCore::InitEncoder()
678 {
679 return false;
680 }
681
UnInitEncoder()682 void CFfmpegCore::UnInitEncoder()
683 {
684 }
685
IsFreqConvertAvailable()686 bool CFfmpegCore::IsFreqConvertAvailable()
687 {
688 return false;
689 }
690
GetVersion()691 int32_t CFfmpegCore::GetVersion() {
692 return version;
693 }
694
IsWASAPISupported()695 bool CFfmpegCore::IsWASAPISupported() {
696 if (ffmpeg_core_is_wasapi_supported) {
697 return ffmpeg_core_is_wasapi_supported();
698 }
699 return false;
700 }
701
EnableWASAPI(bool enable)702 void CFfmpegCore::EnableWASAPI(bool enable) {
703 if (settings && IsSucceed() && ffmpeg_core_settings_set_use_WASAPI) {
704 ffmpeg_core_settings_set_use_WASAPI(settings, enable ? 1 : 0);
705 }
706 }
707
EnableExclusiveMode(bool enable)708 void CFfmpegCore::EnableExclusiveMode(bool enable) {
709 if (settings && IsSucceed() && ffmpeg_core_settings_set_enable_exclusive) {
710 ffmpeg_core_settings_set_enable_exclusive(settings, enable ? 1 : 0);
711 }
712 }
713
SetMaxWaitTime(int max_wait_time)714 void CFfmpegCore::SetMaxWaitTime(int max_wait_time) {
715 if (settings && IsSucceed() && ffmpeg_core_settings_set_max_wait_time) {
716 ffmpeg_core_settings_set_max_wait_time(settings, max_wait_time);
717 }
718 }
719