| 
									
										
										
										
											2019-07-17 19:37:18 +02:00
										 |  |  | #include <iostream>
 | 
					
						
							|  |  |  | #include "../music/providers/shared/pstream.h"
 | 
					
						
							|  |  |  | #include <alsa/asoundlib.h>
 | 
					
						
							|  |  |  | #include <fstream>
 | 
					
						
							|  |  |  | #include <chrono>
 | 
					
						
							| 
									
										
										
										
											2020-02-21 20:32:25 +01:00
										 |  |  | #include <teaspeak/MusicPlayer.h>
 | 
					
						
							| 
									
										
										
										
											2019-07-17 19:37:18 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <log/LogUtils.h>
 | 
					
						
							|  |  |  | #include <CXXTerminal/Terminal.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define PCM_DEVICE "default"
 | 
					
						
							|  |  |  | using namespace std; | 
					
						
							|  |  |  | using namespace std::chrono; | 
					
						
							|  |  |  | using namespace music; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-21 20:32:25 +01:00
										 |  |  | void die(const char *message) { | 
					
						
							| 
									
										
										
										
											2019-07-17 19:37:18 +02:00
										 |  |  |     fprintf(stderr, "%s\n", message); | 
					
						
							|  |  |  |     exit(1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-21 20:32:25 +01:00
										 |  |  | int main(int, char **) { | 
					
						
							|  |  |  |     auto config = std::make_shared<logger::LoggerConfig>(); | 
					
						
							|  |  |  |     config->logfileLevel = spdlog::level::off; | 
					
						
							|  |  |  |     config->terminalLevel = spdlog::level::trace; | 
					
						
							|  |  |  |     config->sync = true; | 
					
						
							|  |  |  |     logger::setup(config); | 
					
						
							| 
									
										
										
										
											2019-07-17 19:37:18 +02:00
										 |  |  |     logger::updateLogLevels(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     //youtube-dl -s --dump-json https://www.youtube.com/watch?v=1ifTLj_glhc
 | 
					
						
							|  |  |  |     //ffmpeg -hide_banner -nostats -i <url> -ac 2 -ar 48000 -f s16le -acodec pcm_s16le pipe:1
 | 
					
						
							|  |  |  |     //
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     //printf("Length: %d\n", codec_context->frame_size / codec_context->framerate.den / codec_context->channels); //576 | 3
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-21 20:32:25 +01:00
										 |  |  |     music::manager::loadProviders("../../music/bin/providers/"); | 
					
						
							| 
									
										
										
										
											2019-07-17 19:37:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-21 20:32:25 +01:00
										 |  |  | #if false
 | 
					
						
							| 
									
										
										
										
											2019-07-17 19:37:18 +02:00
										 |  |  |     std::string file = "https://www.youtube.com/watch?v=GVC5adzPpiE"; //https://www.youtube.com/watch?v=eBlg2oX0Z0Q
 | 
					
						
							|  |  |  |     auto provider = music::manager::resolveProvider("YouTube", file); //test.mp3
 | 
					
						
							|  |  |  |     if(!provider) return 0; | 
					
						
							|  |  |  |     cout << "Using provider -> " << provider->providerName << endl; | 
					
						
							|  |  |  |     cout << "Using provider -> " << provider->providerDescription << endl; | 
					
						
							|  |  |  |     if(true) return 0; | 
					
						
							| 
									
										
										
										
											2020-02-21 20:32:25 +01:00
										 |  |  | #endif
 | 
					
						
							|  |  |  |     constexpr auto url = "https://streams.ilovemusic.de/iloveradio1.mp3"; | 
					
						
							|  |  |  |     auto provider = music::manager::resolveProvider("ffmpeg", url); | 
					
						
							|  |  |  |     if (!provider) return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto player = provider->createPlayer(url, nullptr, nullptr).waitAndGet(nullptr); | 
					
						
							|  |  |  |     if (!player) { | 
					
						
							| 
									
										
										
										
											2019-07-17 19:37:18 +02:00
										 |  |  |         cerr << "Could not load youtube video" << endl; | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-02-21 20:32:25 +01:00
										 |  |  |     if (!player->initialize(2)) { | 
					
						
							| 
									
										
										
										
											2019-07-17 19:37:18 +02:00
										 |  |  |         log::log(log::err, "Could not inizalisze ffmpeg player -> " + player->error()); | 
					
						
							|  |  |  |         return 1; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-02-21 20:32:25 +01:00
										 |  |  |     player->registerEventHandler("main", [player](music::MusicEvent event) { //FIXME weak ptr
 | 
					
						
							| 
									
										
										
										
											2019-07-17 19:37:18 +02:00
										 |  |  |         log::log(log::info, "Got event " + to_string(event)); | 
					
						
							| 
									
										
										
										
											2020-02-21 20:32:25 +01:00
										 |  |  |         if (event == music::EVENT_ERROR) { | 
					
						
							| 
									
										
										
										
											2019-07-17 19:37:18 +02:00
										 |  |  |             log::log(log::err, "Recived error: " + player->error()); | 
					
						
							|  |  |  |             player->clearError(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     player->play(); | 
					
						
							| 
									
										
										
										
											2020-02-21 20:32:25 +01:00
										 |  |  |     //player->forward(chrono::minutes(0));
 | 
					
						
							| 
									
										
										
										
											2019-07-17 19:37:18 +02:00
										 |  |  |     cout << "Song length " << duration_cast<seconds>(player->length()).count() << " seconds" << endl; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-21 20:32:25 +01:00
										 |  |  |     std::this_thread::sleep_for(std::chrono::seconds{600}); | 
					
						
							| 
									
										
										
										
											2019-07-17 19:37:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-21 20:32:25 +01:00
										 |  |  | #if false
 | 
					
						
							|  |  |  |     snd_pcm_t *pcm{nullptr}; | 
					
						
							|  |  |  |     int err, tmp, dir; | 
					
						
							| 
									
										
										
										
											2019-07-17 19:37:18 +02:00
										 |  |  |     snd_pcm_t *pcm_handle; | 
					
						
							|  |  |  |     snd_pcm_hw_params_t *params; | 
					
						
							|  |  |  |     snd_pcm_uframes_t frames; | 
					
						
							|  |  |  |     int loops; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int channels = 2; | 
					
						
							| 
									
										
										
										
											2020-02-21 20:32:25 +01:00
										 |  |  |     unsigned int rate = 48000; | 
					
						
							| 
									
										
										
										
											2019-07-17 19:37:18 +02:00
										 |  |  |     int seconds = duration_cast<std::chrono::seconds>(player->length()).count() + 1; | 
					
						
							|  |  |  |     seconds = 10000; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-21 20:32:25 +01:00
										 |  |  |     if (err = snd_pcm_open(&pcm_handle, PCM_DEVICE, SND_PCM_STREAM_PLAYBACK, 0); err < 0) | 
					
						
							|  |  |  |         printf("ERROR: Can't open \"%s\" PCM device. %s\n", PCM_DEVICE, snd_strerror(err)); | 
					
						
							| 
									
										
										
										
											2019-07-17 19:37:18 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     snd_pcm_hw_params_alloca(¶ms); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     snd_pcm_hw_params_any(pcm_handle, params); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-21 20:32:25 +01:00
										 |  |  |     if (err = snd_pcm_hw_params_set_access(pcm_handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); err < 0) | 
					
						
							|  |  |  |         printf("ERROR: Can't set interleaved mode. %s\n", snd_strerror(err)); | 
					
						
							| 
									
										
										
										
											2019-07-17 19:37:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-21 20:32:25 +01:00
										 |  |  |     if (err = snd_pcm_hw_params_set_format(pcm_handle, params, SND_PCM_FORMAT_S16_LE); err < 0) | 
					
						
							|  |  |  |         printf("ERROR: Can't set format. %s\n", snd_strerror(err)); | 
					
						
							| 
									
										
										
										
											2019-07-17 19:37:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-21 20:32:25 +01:00
										 |  |  |     if (err = snd_pcm_hw_params_set_channels(pcm_handle, params, channels); err < 0) | 
					
						
							|  |  |  |         printf("ERROR: Can't set channels number. %s\n", snd_strerror(err)); | 
					
						
							| 
									
										
										
										
											2019-07-17 19:37:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-21 20:32:25 +01:00
										 |  |  |     if (err = snd_pcm_hw_params_set_rate_near(pcm_handle, params, &rate, 0); err < 0) | 
					
						
							|  |  |  |         printf("ERROR: Can't set rate. %s\n", snd_strerror(err)); | 
					
						
							| 
									
										
										
										
											2019-07-17 19:37:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-21 20:32:25 +01:00
										 |  |  |     if (err = snd_pcm_hw_params(pcm_handle, params); err < 0) | 
					
						
							|  |  |  |         printf("ERROR: Can't set harware parameters. %s\n", snd_strerror(err)); | 
					
						
							| 
									
										
										
										
											2019-07-17 19:37:18 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     printf("PCM name: '%s'\n", snd_pcm_name(pcm_handle)); | 
					
						
							|  |  |  |     printf("PCM state: %s\n", snd_pcm_state_name(snd_pcm_state(pcm_handle))); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     snd_pcm_hw_params_get_channels(params, &tmp); | 
					
						
							|  |  |  |     printf("channels: %i ", tmp); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (tmp == 1) | 
					
						
							|  |  |  |         printf("(mono)\n"); | 
					
						
							|  |  |  |     else if (tmp == 2) | 
					
						
							|  |  |  |         printf("(stereo)\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     snd_pcm_hw_params_get_rate(params, &tmp, 0); | 
					
						
							|  |  |  |     printf("rate: %d bps\n", tmp); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     printf("seconds: %d\n", seconds); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-21 20:32:25 +01:00
										 |  |  |     snd_pcm_hw_params_get_period_size(params, &frames, nullptr); | 
					
						
							| 
									
										
										
										
											2019-07-17 19:37:18 +02:00
										 |  |  |     cout << "perd size: " << frames << endl; | 
					
						
							| 
									
										
										
										
											2020-02-21 20:32:25 +01:00
										 |  |  |     snd_pcm_hw_params_get_period_time(params, &tmp, nullptr); | 
					
						
							| 
									
										
										
										
											2019-07-17 19:37:18 +02:00
										 |  |  |     player->preferredSampleCount(frames); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto last = system_clock::now(); | 
					
						
							|  |  |  |     for (loops = seconds * 1000000 / tmp; loops > 0; loops--) { | 
					
						
							|  |  |  |         //cout << " dur: " << duration_cast<microseconds>(system_clock::now() - last).count() << endl;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         auto next = player->popNextSegment(); | 
					
						
							| 
									
										
										
										
											2020-02-21 20:32:25 +01:00
										 |  |  |         if (!next) { | 
					
						
							| 
									
										
										
										
											2019-07-17 19:37:18 +02:00
										 |  |  |             log::log(log::info, "END!"); | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         retry: | 
					
						
							| 
									
										
										
										
											2020-02-21 20:32:25 +01:00
										 |  |  |         if (err = snd_pcm_writei(pcm_handle, next->segments, next->segmentLength); err == -EPIPE) { | 
					
						
							| 
									
										
										
										
											2019-07-17 19:37:18 +02:00
										 |  |  |             printf("XRUN.\n"); | 
					
						
							|  |  |  |             snd_pcm_prepare(pcm_handle); | 
					
						
							|  |  |  |             goto retry; | 
					
						
							|  |  |  |         } else if (pcm < 0) { | 
					
						
							| 
									
										
										
										
											2020-02-21 20:32:25 +01:00
										 |  |  |             printf("ERROR. Can't write to PCM device. %s\n", snd_strerror(err)); | 
					
						
							| 
									
										
										
										
											2019-07-17 19:37:18 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |         //if((system_clock::now() - last) > ::seconds(1)) {
 | 
					
						
							| 
									
										
										
										
											2020-02-21 20:32:25 +01:00
										 |  |  |         log::log(log::debug, | 
					
						
							|  |  |  |                  "Time: " + to_string(duration_cast<milliseconds>(system_clock::now() - last).count()) + " | " + | 
					
						
							|  |  |  |                  to_string(duration_cast<milliseconds>(player->currentIndex()).count())); | 
					
						
							|  |  |  |         last = system_clock::now(); | 
					
						
							| 
									
										
										
										
											2019-07-17 19:37:18 +02:00
										 |  |  |         //}
 | 
					
						
							|  |  |  |         //TODO!
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     snd_pcm_drain(pcm_handle); | 
					
						
							|  |  |  |     snd_pcm_close(pcm_handle); | 
					
						
							| 
									
										
										
										
											2020-02-21 20:32:25 +01:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-07-17 19:37:18 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } |