mirror of
				https://github.com/SuperBFG7/ympd
				synced 2025-10-31 13:53:00 +00:00 
			
		
		
		
	Output json with frozen
This commit is contained in:
		| @@ -7,13 +7,13 @@ set(CPACK_PACKAGE_VERSION_MINOR "0") | ||||
| set(CPACK_PACKAGE_VERSION_PATCH "0") | ||||
| if(CMAKE_BUILD_TYPE MATCHES RELEASE) | ||||
|     set(ASSETS_PATH "${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME}/htdocs") | ||||
|     set(DEBUG "OFF") | ||||
| else() | ||||
|     set(ASSETS_PATH "${PROJECT_SOURCE_DIR}/htdocs") | ||||
|     set(DEBUG ON) | ||||
|     set(DEBUG "ON") | ||||
| endif() | ||||
|  | ||||
| option(WITH_IPV6 "enable IPv6 support" ON) | ||||
| option(WITH_SSL "enable SSL support" ON) | ||||
|  | ||||
| find_package(LibMPDClient REQUIRED) | ||||
| find_package(Threads REQUIRED) | ||||
| @@ -23,17 +23,11 @@ include_directories(${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR}	${LIBMPDCLIENT_I | ||||
|  | ||||
| include(CheckCSourceCompiles) | ||||
|  | ||||
| #set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -Wall -Wextra -pedantic") | ||||
| set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -Wall -Wextra -pedantic -D_FORTIFY_SOURCE=2 -fstack-protector -fsanitize=address -fno-omit-frame-pointer -fsanitize=undefined -fsanitize=shift -fsanitize=integer-divide-by-zero -fsanitize=unreachable -fsanitize=vla-bound -fsanitize=null -fsanitize=return -fsanitize=signed-integer-overflow -fsanitize=bounds -fsanitize=bounds-strict -fsanitize=alignment -fsanitize=object-size -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fsanitize=nonnull-attribute -fsanitize=returns-nonnull-attribute -fsanitize=bool -fsanitize=enum -fsanitize=vptr -static-libasan") | ||||
| set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -ggdb") | ||||
| set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -Wall -Wextra -pedantic ") | ||||
| set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -ggdb -D_FORTIFY_SOURCE=2 -fstack-protector -fsanitize=address -fno-omit-frame-pointer -fsanitize=undefined -fsanitize=shift -fsanitize=integer-divide-by-zero -fsanitize=unreachable -fsanitize=vla-bound -fsanitize=null -fsanitize=return -fsanitize=signed-integer-overflow -fsanitize=bounds -fsanitize=bounds-strict -fsanitize=alignment -fsanitize=object-size -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fsanitize=nonnull-attribute -fsanitize=returns-nonnull-attribute -fsanitize=bool -fsanitize=enum -fsanitize=vptr -static-libasan") | ||||
| if(WITH_IPV6) | ||||
|     set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS NS_ENABLE_IPV6) | ||||
| endif() | ||||
| if(WITH_SSL) | ||||
|     find_package(OpenSSL REQUIRED) | ||||
|     include_directories(${OPENSSL_INCLUDE_DIR}) | ||||
|     set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS NS_ENABLE_SSL) | ||||
| endif() | ||||
|  | ||||
| file(GLOB RESOURCES  | ||||
|     RELATIVE ${PROJECT_SOURCE_DIR} | ||||
| @@ -54,7 +48,7 @@ set(SOURCES | ||||
| ) | ||||
|  | ||||
| add_executable(mympd ${SOURCES}) | ||||
| target_link_libraries(mympd ${LIBMPDCLIENT_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${OPENSSL_LIBRARIES}) | ||||
| target_link_libraries(mympd ${LIBMPDCLIENT_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) | ||||
|  | ||||
| install(TARGETS mympd DESTINATION bin) | ||||
| install(FILES mympd.1 DESTINATION ${CMAKE_INSTALL_PREFIX}/share/man/man1) | ||||
|   | ||||
							
								
								
									
										17
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								README.md
									
									
									
									
									
								
							| @@ -27,12 +27,11 @@ Dependencies | ||||
| ------------ | ||||
|  - libmpdclient 2: http://www.musicpd.org/libs/libmpdclient/ | ||||
|  - cmake 2.6: http://cmake.org/ | ||||
|  - OpenSSL: https://www.openssl.org/ | ||||
|  | ||||
| Unix Build Instructions | ||||
| ----------------------- | ||||
|  | ||||
| 1. install dependencies. cmake, libmpdclient (dev), and OpenSSL (dev) are available from all major distributions. | ||||
| 1. install dependencies. cmake and libmpdclient (dev) are available from all major distributions. | ||||
| 2. create build directory ```cd /path/to/src; mkdir build; cd build``` | ||||
| 3. create makefile ```cmake ..  -DCMAKE_INSTALL_PREFIX:PATH=/usr -DCMAKE_BUILD_TYPE=RELEASE``` | ||||
| 4. build ```make``` | ||||
| @@ -56,20 +55,6 @@ Usage: ./mympd [OPTION]... | ||||
|  --help                        this help | ||||
| ``` | ||||
|  | ||||
| SSL Support | ||||
| ----------- | ||||
| To run myMPD with SSL support: | ||||
|  | ||||
| - create a certificate (key and cert in the same file), example: | ||||
| ``` | ||||
| # openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 1000 -nodes -sha256 | ||||
| # cat key.pem cert.pem > ssl.pem | ||||
| ``` | ||||
| - tell myMPD to use a webport using SSL and where to find the certificate:  | ||||
| ``` | ||||
| # ./mympd -w "ssl://8081:/path/to/ssl.pem" | ||||
| ``` | ||||
|  | ||||
| Copyright | ||||
| --------- | ||||
| ympd: 2013-2014 <andy@ndyk.de> | ||||
|   | ||||
							
								
								
									
										137
									
								
								src/mpd_client.c
									
									
									
									
									
								
							
							
						
						
									
										137
									
								
								src/mpd_client.c
									
									
									
									
									
								
							| @@ -754,9 +754,10 @@ int mympd_put_state(char *buffer, int *current_song_id, int *next_song_id,  unsi | ||||
| { | ||||
|     struct mpd_status *status; | ||||
|     const struct mpd_audio_format *audioformat; | ||||
|     struct mpd_output *out; | ||||
|     char *cur = buffer; | ||||
|     const char *end = buffer + MAX_SIZE; | ||||
|     struct mpd_output *output; | ||||
|     int len; | ||||
|     int nr; | ||||
|     struct json_out out = JSON_OUT_BUF(buffer, MAX_SIZE); | ||||
|  | ||||
|     status = mpd_run_status(mpd.conn); | ||||
|     if (!status) { | ||||
| @@ -768,78 +769,73 @@ int mympd_put_state(char *buffer, int *current_song_id, int *next_song_id,  unsi | ||||
|      audioformat = mpd_status_get_audio_format(status); | ||||
|     } | ||||
|      | ||||
|     cur += json_emit_raw_str(cur, end - cur, "{\"type\": \"state\", \"data\":{\"state\":"); | ||||
|     cur += json_emit_int(cur, end - cur, mpd_status_get_state(status)); | ||||
|     cur += json_emit_raw_str(cur, end - cur, ",\"volume\":"); | ||||
|     cur += json_emit_int(cur, end - cur, mpd_status_get_volume(status));     | ||||
|     cur += json_emit_raw_str(cur, end - cur, ",\"songpos\":"); | ||||
|     cur += json_emit_int(cur, end - cur, mpd_status_get_song_pos(status)); | ||||
|     cur += json_emit_raw_str(cur, end - cur, ",\"elapsedTime\":"); | ||||
|     cur += json_emit_int(cur, end - cur, mpd_status_get_elapsed_time(status)); | ||||
|     cur += json_emit_raw_str(cur, end - cur, ",\"totalTime\":"); | ||||
|     cur += json_emit_int(cur, end - cur, mpd_status_get_total_time(status)); | ||||
|     cur += json_emit_raw_str(cur, end - cur, ",\"currentsongid\":"); | ||||
|     cur += json_emit_int(cur, end - cur, mpd_status_get_song_id(status)); | ||||
|     cur += json_emit_raw_str(cur, end - cur, ",\"kbitrate\":"); | ||||
|     cur += json_emit_int(cur, end - cur, mpd_status_get_kbit_rate(status)); | ||||
|     cur += json_emit_raw_str(cur, end - cur, ",\"audioformat\": {"); | ||||
|     cur += json_emit_raw_str(cur, end - cur, "\"sample_rate\":"); | ||||
|     cur += json_emit_int(cur, end - cur, audioformat ? audioformat->sample_rate : 0); | ||||
|     cur += json_emit_raw_str(cur, end - cur, ",\"bits\":"); | ||||
|     cur += json_emit_int(cur, end - cur, audioformat ? audioformat->bits : 0); | ||||
|     cur += json_emit_raw_str(cur, end - cur, ",\"channels\":"); | ||||
|     cur += json_emit_int(cur, end - cur, audioformat ? audioformat->channels : 0); | ||||
|     cur += json_emit_raw_str(cur, end - cur, "},\"queue_length\":"); | ||||
|     cur += json_emit_int(cur, end - cur, mpd_status_get_queue_length(status)); | ||||
|     cur += json_emit_raw_str(cur, end - cur, ",\"nextsongpos\":"); | ||||
|     cur += json_emit_int(cur, end - cur, mpd_status_get_next_song_pos(status)); | ||||
|     cur += json_emit_raw_str(cur, end - cur, ",\"nextsongid\":"); | ||||
|     cur += json_emit_int(cur, end - cur, mpd_status_get_next_song_id(status)); | ||||
|     cur += json_emit_raw_str(cur, end - cur, ",\"queue_version\":"); | ||||
|     cur += json_emit_int(cur, end - cur, mpd_status_get_queue_version(status)); | ||||
|     cur += json_emit_raw_str(cur, end - cur, ",\"outputs\": {"); | ||||
|     len = json_printf(&out,"{type:state, data:{" | ||||
|         "state:%d, volume:%d, songpos: %d, elapsedTime: %d, " | ||||
|         "totalTime:%d, currentsongid: %d, kbitrate: %d, " | ||||
|         "audioformat: { sample_rate: %d, bits: %d, channels: %d}, " | ||||
|         "queue_length: %d, nextsongpos: %d, nextsongid: %d, " | ||||
|         "queue_version: %d",  | ||||
|         mpd_status_get_state(status), | ||||
|         mpd_status_get_volume(status),  | ||||
|         mpd_status_get_song_pos(status), | ||||
|         mpd_status_get_elapsed_time(status), | ||||
|         mpd_status_get_total_time(status), | ||||
|         mpd_status_get_song_id(status), | ||||
|         mpd_status_get_kbit_rate(status), | ||||
|         audioformat ? audioformat->sample_rate : 0,  | ||||
|         audioformat ? audioformat->bits : 0,  | ||||
|         audioformat ? audioformat->channels : 0, | ||||
|         mpd_status_get_queue_length(status), | ||||
|         mpd_status_get_next_song_pos(status), | ||||
|         mpd_status_get_next_song_id(status), | ||||
|         mpd_status_get_queue_version(status) | ||||
|     ); | ||||
|      | ||||
|     len += json_printf(&out, ",outputs: {"); | ||||
|  | ||||
|     mpd_send_outputs(mpd.conn); | ||||
|     while ((out = mpd_recv_output(mpd.conn)) != NULL) { | ||||
|         cur += json_emit_raw_str(cur, end - cur, "\""); | ||||
|         cur += json_emit_int(cur, end - cur, mpd_output_get_id(out)); | ||||
|         cur += json_emit_raw_str(cur, end - cur, "\":"); | ||||
|         cur += json_emit_int(cur, end - cur, mpd_output_get_enabled(out)); | ||||
|         cur += json_emit_raw_str(cur, end - cur, ","); | ||||
|         mpd_output_free(out); | ||||
|     nr=0; | ||||
|     while ((output = mpd_recv_output(mpd.conn)) != NULL) { | ||||
|         if (nr++) len += json_printf(&out, ","); | ||||
|         len += json_printf(&out, "\"%d\":%d", | ||||
|             mpd_output_get_id(output),  | ||||
|             mpd_output_get_enabled(output) | ||||
|         ); | ||||
|         mpd_output_free(output); | ||||
|     } | ||||
|     if (!mpd_response_finish(mpd.conn)) { | ||||
|         fprintf(stderr, "MPD outputs: %s\n", mpd_connection_get_error_message(mpd.conn)); | ||||
|         mpd_connection_clear_error(mpd.conn); | ||||
|     } | ||||
|  | ||||
|     cur --; | ||||
|     cur += json_emit_raw_str(cur, end - cur, "}}}"); | ||||
|     len += json_printf(&out, "}}}"); | ||||
|  | ||||
|     *current_song_id = mpd_status_get_song_id(status); | ||||
|     *next_song_id = mpd_status_get_next_song_id(status); | ||||
|     *queue_version = mpd_status_get_queue_version(status); | ||||
|     mpd_status_free(status); | ||||
|     return cur - buffer; | ||||
|  | ||||
|     if (len > MAX_SIZE) fprintf(stderr,"Buffer truncated\n"); | ||||
|     return len; | ||||
| } | ||||
|  | ||||
| int mympd_put_welcome(char *buffer) | ||||
| { | ||||
|     int len; | ||||
|     len = snprintf(buffer, MAX_SIZE, | ||||
|         "{\"type\":\"welcome\", \"data\":{" | ||||
|         "\"version\":\"%s\"}}",  | ||||
|         MYMPD_VERSION | ||||
|     ); | ||||
|     struct json_out out = JSON_OUT_BUF(buffer, MAX_SIZE); | ||||
|      | ||||
|     len = json_printf(&out, "{type: %Q, data: { version: %Q}}", "welcome", MYMPD_VERSION); | ||||
|      | ||||
|     if (len > MAX_SIZE) fprintf(stderr,"Buffer truncated\n"); | ||||
|     return len; | ||||
| } | ||||
|  | ||||
| int mympd_put_settings(char *buffer) | ||||
| { | ||||
|     struct mpd_status *status; | ||||
|     int len; | ||||
|     char *replaygain; | ||||
|     int len; | ||||
|     struct json_out out = JSON_OUT_BUF(buffer, MAX_SIZE); | ||||
|  | ||||
|     status = mpd_run_status(mpd.conn); | ||||
|     if (!status) { | ||||
| @@ -855,11 +851,11 @@ int mympd_put_settings(char *buffer) | ||||
| 	mpd_return_pair(mpd.conn, pair); | ||||
|     } | ||||
| 			 | ||||
|     len = snprintf(buffer, MAX_SIZE, | ||||
|         "{\"type\":\"settings\", \"data\":{" | ||||
|         "\"repeat\":%d, \"single\":%d, \"crossfade\":%d, \"consume\":%d, \"random\":%d, " | ||||
|         "\"mixrampdb\": %f, \"mixrampdelay\": %f, \"mpdhost\" : \"%s\", \"mpdport\": \"%d\", \"passwort_set\": %s, " | ||||
|         "\"streamport\": \"%d\",\"coverimage\": \"%s\", \"max_elements_per_page\": %d, \"replaygain\": \"%s\"" | ||||
|     len = json_printf(&out, | ||||
|         "{type:settings, data:{" | ||||
|         "repeat:%d, single:%d, crossfade:%d, consume:%d, random:%d, " | ||||
|         "mixrampdb: %f, mixrampdelay: %f, mpdhost : %Q, mpdport: %d, passwort_set: %B, " | ||||
|         "streamport: %d, coverimage: %Q, max_elements_per_page: %d, replaygain: %Q" | ||||
|         "}}",  | ||||
|         mpd_status_get_repeat(status), | ||||
|         mpd_status_get_single(status), | ||||
| @@ -875,37 +871,40 @@ int mympd_put_settings(char *buffer) | ||||
|         replaygain | ||||
|     ); | ||||
|     mpd_status_free(status); | ||||
|  | ||||
|     if (len > MAX_SIZE) fprintf(stderr,"Buffer truncated\n"); | ||||
|     return len; | ||||
| } | ||||
|  | ||||
|  | ||||
| int mympd_put_outputnames(char *buffer) | ||||
| { | ||||
|     char *cur = buffer; | ||||
|     const char *end = buffer + MAX_SIZE; | ||||
|     struct mpd_output *out; | ||||
|     struct mpd_output *output; | ||||
|     int len; | ||||
|     int nr; | ||||
|     struct json_out out = JSON_OUT_BUF(buffer, MAX_SIZE); | ||||
|      | ||||
|     cur += json_emit_raw_str(cur, end - cur, "{\"type\": \"outputnames\", \"data\":{"); | ||||
|     len = json_printf(&out,"{type: outputnames, data:{"); | ||||
|      | ||||
|     mpd_send_outputs(mpd.conn); | ||||
|      | ||||
|     while ((out = mpd_recv_output(mpd.conn)) != NULL) { | ||||
|         cur += json_emit_raw_str(cur, end - cur, "\""); | ||||
|         cur += json_emit_int(cur, end - cur, mpd_output_get_id(out)); | ||||
|         cur += json_emit_raw_str(cur, end - cur, "\":"); | ||||
|         cur += json_emit_quoted_str(cur, end - cur, mpd_output_get_name(out)); | ||||
|         cur += json_emit_raw_str(cur, end - cur, ","); | ||||
|         mpd_output_free(out); | ||||
|     nr=0;     | ||||
|     while ((output = mpd_recv_output(mpd.conn)) != NULL) { | ||||
|         if (nr++) len += json_printf(&out, ","); | ||||
|         len += json_printf(&out,"\"%d\":%Q", | ||||
|             mpd_output_get_id(output), | ||||
|             mpd_output_get_name(output) | ||||
|         ); | ||||
|         mpd_output_free(output); | ||||
|     } | ||||
|     if (!mpd_response_finish(mpd.conn)) { | ||||
|         fprintf(stderr, "MPD outputs: %s\n", mpd_connection_get_error_message(mpd.conn)); | ||||
|         mpd_connection_clear_error(mpd.conn); | ||||
|     } | ||||
|  | ||||
|     cur --; | ||||
|     cur += json_emit_raw_str(cur, end - cur, "}}"); | ||||
|     len += json_printf(&out,"}}"); | ||||
|      | ||||
|     return cur - buffer; | ||||
|     if (len > MAX_SIZE) fprintf(stderr,"Buffer truncated\n"); | ||||
|     return len; | ||||
| } | ||||
|  | ||||
| int mympd_put_current_song(char *buffer) | ||||
|   | ||||
| @@ -132,6 +132,7 @@ struct t_mpd_client_session { | ||||
| }; | ||||
|  | ||||
| void mympd_poll(struct mg_mgr *s); | ||||
| void callback_mympd_jsonrpc(struct mg_connection *nc, const struct mg_str msg); | ||||
| void callback_mympd(struct mg_connection *nc, const struct mg_str msg); | ||||
| int mympd_close_handler(struct mg_connection *c); | ||||
| int mympd_put_state(char *buffer, int *current_song_id, int *next_song_id, unsigned *queue_version); | ||||
|   | ||||
| @@ -142,7 +142,7 @@ int main(int argc, char **argv) | ||||
|         {0,              0,                 0,  0 } | ||||
|     }; | ||||
|  | ||||
|     while((n = getopt_long(argc, argv, "D:h:p:w:u:vm:s:i:", | ||||
|     while((n = getopt_long(argc, argv, "D:h:p:w:u:vm:s:i:c:", | ||||
|                 long_options, &option_index)) != -1) { | ||||
|         switch (n) { | ||||
|             case 'D': | ||||
| @@ -203,7 +203,7 @@ int main(int argc, char **argv) | ||||
|  | ||||
|     nc = mg_bind(&mgr, webport, ev_handler); | ||||
|     if (nc == NULL) { | ||||
|        printf("myMPD can't bind to port %s\n", webport); | ||||
|        fprintf(stderr, "Error starting server on port %s\n", webport); | ||||
|        return EXIT_FAILURE; | ||||
|     } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 jcorporation
					jcorporation