From 1508a5ce6b9f7c2df009619fa822babaf7c533db Mon Sep 17 00:00:00 2001 From: Koki Shinjo Date: Fri, 5 Nov 2021 13:43:31 +0900 Subject: [PATCH 01/12] [audio_video_recorder_server] add audio_video_recorder package --- audio_video_recorder_server/CMakeLists.txt | 115 ++++++++++++++++++ .../launch/audio_video_recorder.launch | 34 ++++++ .../msg/RecordTask.msg | 14 +++ .../msg/RecordTaskArray.msg | 1 + audio_video_recorder_server/package.xml | 22 ++++ audio_video_recorder_server/setup.py | 10 ++ .../audio_video_recorder_server/__init__.py | 0 .../audio_video_recorder_server.py | 94 ++++++++++++++ .../srv/StartRecord.srv | 4 + .../srv/StopRecord.srv | 4 + 10 files changed, 298 insertions(+) create mode 100644 audio_video_recorder_server/CMakeLists.txt create mode 100644 audio_video_recorder_server/launch/audio_video_recorder.launch create mode 100644 audio_video_recorder_server/msg/RecordTask.msg create mode 100644 audio_video_recorder_server/msg/RecordTaskArray.msg create mode 100644 audio_video_recorder_server/package.xml create mode 100644 audio_video_recorder_server/setup.py create mode 100644 audio_video_recorder_server/src/audio_video_recorder_server/__init__.py create mode 100644 audio_video_recorder_server/src/audio_video_recorder_server/audio_video_recorder_server.py create mode 100644 audio_video_recorder_server/srv/StartRecord.srv create mode 100644 audio_video_recorder_server/srv/StopRecord.srv diff --git a/audio_video_recorder_server/CMakeLists.txt b/audio_video_recorder_server/CMakeLists.txt new file mode 100644 index 000000000..c01cca7a8 --- /dev/null +++ b/audio_video_recorder_server/CMakeLists.txt @@ -0,0 +1,115 @@ +cmake_minimum_required(VERSION 3.0.2) +project(audio_video_recorder_server) + +find_package(catkin REQUIRED + roscpp + rospy + message_generation +) + +catkin_python_setup() + +add_message_files( + FILES + RecordTask.msg + RecordTaskArray.msg +) + +add_service_files( + FILES + StartRecord.srv + StopRecord.srv +) + +generate_messages( + DEPENDENCIES +) + +catkin_package( +) + + +## Declare a C++ library +# add_library(${PROJECT_NAME} +# src/${PROJECT_NAME}/audio_video_recorder_server.cpp +# ) + +## Add cmake target dependencies of the library +## as an example, code may need to be generated before libraries +## either from message generation or dynamic reconfigure +# add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) + +## Declare a C++ executable +## With catkin_make all packages are built within a single CMake context +## The recommended prefix ensures that target names across packages don't collide +# add_executable(${PROJECT_NAME}_node src/audio_video_recorder_server_node.cpp) + +## Rename C++ executable without prefix +## The above recommended prefix causes long target names, the following renames the +## target back to the shorter version for ease of user use +## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node" +# set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "") + +## Add cmake target dependencies of the executable +## same as for the library above +# add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) + +## Specify libraries to link a library or executable target against +# target_link_libraries(${PROJECT_NAME}_node +# ${catkin_LIBRARIES} +# ) + +############# +## Install ## +############# + +# all install targets should use catkin DESTINATION variables +# See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html + +## Mark executable scripts (Python etc.) for installation +## in contrast to setup.py, you can choose the destination +# catkin_install_python(PROGRAMS +# scripts/my_python_script +# DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} +# ) + +## Mark executables for installation +## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_executables.html +# install(TARGETS ${PROJECT_NAME}_node +# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} +# ) + +## Mark libraries for installation +## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_libraries.html +# install(TARGETS ${PROJECT_NAME} +# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} +# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} +# RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION} +# ) + +## Mark cpp header files for installation +# install(DIRECTORY include/${PROJECT_NAME}/ +# DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} +# FILES_MATCHING PATTERN "*.h" +# PATTERN ".svn" EXCLUDE +# ) + +## Mark other files for installation (e.g. launch and bag files, etc.) +# install(FILES +# # myfile1 +# # myfile2 +# DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} +# ) + +############# +## Testing ## +############# + +## Add gtest based cpp test target and link libraries +# catkin_add_gtest(${PROJECT_NAME}-test test/test_audio_video_recorder_server.cpp) +# if(TARGET ${PROJECT_NAME}-test) +# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME}) +# endif() + +## Add folders to be run by python nosetests +# catkin_add_nosetests(test) diff --git a/audio_video_recorder_server/launch/audio_video_recorder.launch b/audio_video_recorder_server/launch/audio_video_recorder.launch new file mode 100644 index 000000000..d7ccad13c --- /dev/null +++ b/audio_video_recorder_server/launch/audio_video_recorder.launch @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + queue_size: $(arg queue_size) + file_name: $(arg file_name) + file_format: $(arg file_format) + audio_channels: $(arg audio_channels) + audio_sample_rate: $(arg audio_sample_rate) + audio_format: $(arg audio_format) + audio_sample_format: $(arg audio_sample_format) + video_height: $(arg video_height) + video_width: $(arg video_width) + video_framerate: $(arg video_framerate) + video_encoding: $(arg video_encoding) + + + diff --git a/audio_video_recorder_server/msg/RecordTask.msg b/audio_video_recorder_server/msg/RecordTask.msg new file mode 100644 index 000000000..c78a40527 --- /dev/null +++ b/audio_video_recorder_server/msg/RecordTask.msg @@ -0,0 +1,14 @@ +string audio_topic_name +string image_topic_name +int32 queue_size +string file_name # This will be used as key +string file_format +string audio_format +string audio_sample_format +string audio_channels +string audio_depth +string audio_sample_rate +string video_encoding +string video_height +string video_width +string video_framerate diff --git a/audio_video_recorder_server/msg/RecordTaskArray.msg b/audio_video_recorder_server/msg/RecordTaskArray.msg new file mode 100644 index 000000000..f47e6204a --- /dev/null +++ b/audio_video_recorder_server/msg/RecordTaskArray.msg @@ -0,0 +1 @@ +audio_video_recorder_server/RecordTask[] array diff --git a/audio_video_recorder_server/package.xml b/audio_video_recorder_server/package.xml new file mode 100644 index 000000000..8e9f8be57 --- /dev/null +++ b/audio_video_recorder_server/package.xml @@ -0,0 +1,22 @@ + + + audio_video_recorder_server + 0.0.0 + The audio_video_recorder_server package + + Koki Shinjo + Kei Okada + Koki Shinjo + + BSD + + catkin + + roscpp + rospy + message_generation + message_runtime + + + + diff --git a/audio_video_recorder_server/setup.py b/audio_video_recorder_server/setup.py new file mode 100644 index 000000000..d2517a85d --- /dev/null +++ b/audio_video_recorder_server/setup.py @@ -0,0 +1,10 @@ +from distutils.core import setup +from catkin_pkg.python_setup import generate_distutils_setup + +d = generate_distutils_setup( + packages=['audio_video_recorder_server'], + scripts=[], + package_dir={'': 'src'} +) + +setup(**d) diff --git a/audio_video_recorder_server/src/audio_video_recorder_server/__init__.py b/audio_video_recorder_server/src/audio_video_recorder_server/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/audio_video_recorder_server/src/audio_video_recorder_server/audio_video_recorder_server.py b/audio_video_recorder_server/src/audio_video_recorder_server/audio_video_recorder_server.py new file mode 100644 index 000000000..729bdc4c5 --- /dev/null +++ b/audio_video_recorder_server/src/audio_video_recorder_server/audio_video_recorder_server.py @@ -0,0 +1,94 @@ +# -*- encoding: utf-8 -*- + +import rospy +import roslaunch + +from audio_video_recorder_server.msg import RecordTask, RecordTaskArray +from audio_video_recorder_server.srv import StartRecord, StopRecord + +import threading + + +def thread_launch_recorder( record_task ): + + uuid = roslaunch.rlutil.get_or_generate_uuid(None, False) + roslaunch_path = rospkg.RosPack().get_path('audio_video_recorder_server') +\ + '/launch/audio_video_recorder.launch' + roslaunch_cli_args = [roslaunch_path] + roslaunch_file = roslaunch.rlutil.resolve_launch_arguments( + roslaunch_cli_args) + roslaunch_parent = roslaunch.parent.ROSLaunchParent( + uuid, + roslaunch_file + ) + roslaunch_parent.start() + + +class AudioVideoRecorderServer: + + def __init__(self): + + self.pub_record_task_array = rospy.Publisher('~record_tasks', RecordTaskArray, queue_size=1) + + self.list_record_task_and_launch = {} + self.lock_for_list = threading.Lock() + + roslaunch.pmon._init_signal_handlers() + + self.srv_start_record = rospy.Service('~start_record', StartRecord, self.handler_start_record) + self.srv_stop_record = rospy.Service('~stop_record', StopRecord, self.handler_stop_record) + + + def __start_record(self, record_task): + + self.lock_for_list.acquire() + + if record_task.file_name in self.list_record_task_and_launch: + self.lock_for_list.release() + return False, 'There is already a recording task with the same name.' + + # start roslaunch + uuid = roslaunch.rlutil.get_or_generate_uuid(None, False) + roslaunch_path = rospkg.RosPack().get_path('audio_video_recorder_server') +\ + '/launch/audio_video_recorder.launch' + roslaunch_cli_args = [ + roslaunch_path, + 'audio_topic_name:={}'.format(record_task.audio_topic_name). + 'image_topic_name:={}'.format(record_task.image_topic_name), + 'queue_size:={}'.format(record_task.queue_size), + 'file_name:={}'.format(record_task.flie_name), + 'file_format:={}'.format(record_task.file_format), + 'audio_format:={}'.format(record_task.audio_format), + 'audio_sample_format:={}'.format(record_task.audio_sample_format), + 'audio_channels:={}'.format(record_task.audio_channels), + ] + roslaunch_file = roslaunch.rlutil.resolve_launch_arguments( + roslaunch_cli_args) + roslaunch_parent = roslaunch.parent.ROSLaunchParent( + uuid, + roslaunch_file + ) + roslaunch_parent.start() + + # Add task to list + self.list_record_task_and_launch[record_task.file_name] = { + 'task': record_task, + 'launch_handler': roslaunch_parent, + } + + self.lock_for_list.release() + return True, 'Success' + + def handler_start_record(self, req): + + uuid = roslaunch.rlutil.get_or_generate_uuid(None, False) + roslaunch_path = rospkg.RosPack().get_path('audio_video_recorder_server') +\ + '/launch/audio_video_recorder.launch' + roslaunch_cli_args = [roslaunch_path] + roslaunch_file = roslaunch.rlutil.resolve_launch_arguments( + roslaunch_cli_args) + self.roslaunch_parent = roslaunch.parent.ROSLaunchParent( + uuid, + roslaunch_file + ) + self.roslaunch_parent.start() diff --git a/audio_video_recorder_server/srv/StartRecord.srv b/audio_video_recorder_server/srv/StartRecord.srv new file mode 100644 index 000000000..c486a30b6 --- /dev/null +++ b/audio_video_recorder_server/srv/StartRecord.srv @@ -0,0 +1,4 @@ +audio_video_recorder_server/RecordTask task +--- +bool success +string message diff --git a/audio_video_recorder_server/srv/StopRecord.srv b/audio_video_recorder_server/srv/StopRecord.srv new file mode 100644 index 000000000..2ad887544 --- /dev/null +++ b/audio_video_recorder_server/srv/StopRecord.srv @@ -0,0 +1,4 @@ +string file_name +--- +bool success +string message From aef6141fbd54b75b472c8430717cfb4c9f11af00 Mon Sep 17 00:00:00 2001 From: Koki Shinjo Date: Fri, 5 Nov 2021 16:15:40 +0900 Subject: [PATCH 02/12] [audio_video_recorder_server] update --- audio_video_recorder_server/CMakeLists.txt | 1 + ...launch => audio_video_recorder.launch.xml} | 0 .../launch/audio_video_recorder_server.launch | 7 ++ .../node_scripts/audio_video_recorder_server | 16 +++ audio_video_recorder_server/package.xml | 3 + .../audio_video_recorder_server.py | 99 +++++++++++-------- 6 files changed, 87 insertions(+), 39 deletions(-) rename audio_video_recorder_server/launch/{audio_video_recorder.launch => audio_video_recorder.launch.xml} (100%) create mode 100644 audio_video_recorder_server/launch/audio_video_recorder_server.launch create mode 100755 audio_video_recorder_server/node_scripts/audio_video_recorder_server diff --git a/audio_video_recorder_server/CMakeLists.txt b/audio_video_recorder_server/CMakeLists.txt index c01cca7a8..bdacebc8d 100644 --- a/audio_video_recorder_server/CMakeLists.txt +++ b/audio_video_recorder_server/CMakeLists.txt @@ -26,6 +26,7 @@ generate_messages( ) catkin_package( + CATKIN_DEPENDS rospy roslaunch ) diff --git a/audio_video_recorder_server/launch/audio_video_recorder.launch b/audio_video_recorder_server/launch/audio_video_recorder.launch.xml similarity index 100% rename from audio_video_recorder_server/launch/audio_video_recorder.launch rename to audio_video_recorder_server/launch/audio_video_recorder.launch.xml diff --git a/audio_video_recorder_server/launch/audio_video_recorder_server.launch b/audio_video_recorder_server/launch/audio_video_recorder_server.launch new file mode 100644 index 000000000..95a01e53c --- /dev/null +++ b/audio_video_recorder_server/launch/audio_video_recorder_server.launch @@ -0,0 +1,7 @@ + + + diff --git a/audio_video_recorder_server/node_scripts/audio_video_recorder_server b/audio_video_recorder_server/node_scripts/audio_video_recorder_server new file mode 100755 index 000000000..c50ad42b9 --- /dev/null +++ b/audio_video_recorder_server/node_scripts/audio_video_recorder_server @@ -0,0 +1,16 @@ +#!/usr/bin/env python +# -*- encoding: utf-8 -*- + +import rospy +from audio_video_recorder_server.audio_video_recorder_server import AudioVideoRecorderServer + + +def main(): + + rospy.init_node('audio_video_recorder_server') + server = AudioVideoRecorderServer() + server.spin() + + +if __name__=='__main__': + main() diff --git a/audio_video_recorder_server/package.xml b/audio_video_recorder_server/package.xml index 8e9f8be57..d1051290a 100644 --- a/audio_video_recorder_server/package.xml +++ b/audio_video_recorder_server/package.xml @@ -15,7 +15,10 @@ roscpp rospy message_generation + audio_video_recorder message_runtime + roslaunch + rospy diff --git a/audio_video_recorder_server/src/audio_video_recorder_server/audio_video_recorder_server.py b/audio_video_recorder_server/src/audio_video_recorder_server/audio_video_recorder_server.py index 729bdc4c5..bd9887ea7 100644 --- a/audio_video_recorder_server/src/audio_video_recorder_server/audio_video_recorder_server.py +++ b/audio_video_recorder_server/src/audio_video_recorder_server/audio_video_recorder_server.py @@ -3,27 +3,13 @@ import rospy import roslaunch -from audio_video_recorder_server.msg import RecordTask, RecordTaskArray -from audio_video_recorder_server.srv import StartRecord, StopRecord +from .msg import RecordTask, RecordTaskArray +from .srv import StartRecord, StartRecordRequest, StartRecordResponse +from .srv import StopRecord, StopRecordRequest, StopRecordResponse import threading -def thread_launch_recorder( record_task ): - - uuid = roslaunch.rlutil.get_or_generate_uuid(None, False) - roslaunch_path = rospkg.RosPack().get_path('audio_video_recorder_server') +\ - '/launch/audio_video_recorder.launch' - roslaunch_cli_args = [roslaunch_path] - roslaunch_file = roslaunch.rlutil.resolve_launch_arguments( - roslaunch_cli_args) - roslaunch_parent = roslaunch.parent.ROSLaunchParent( - uuid, - roslaunch_file - ) - roslaunch_parent.start() - - class AudioVideoRecorderServer: def __init__(self): @@ -38,22 +24,28 @@ def __init__(self): self.srv_start_record = rospy.Service('~start_record', StartRecord, self.handler_start_record) self.srv_stop_record = rospy.Service('~stop_record', StopRecord, self.handler_stop_record) + def __publish_tasks(self): + + self.lock_for_list.acquire() + msg = RecordTaskArray() + for key, item in self.list_record_task_and_launch.items(): + msg.array.append(item['task']) + self.pub_record_task_array.publish(msg) + self.lock_for_list.release() def __start_record(self, record_task): + if not isinstance(record_task, RecordTask): + return False, 'Argument is not an instance of RecordTask' self.lock_for_list.acquire() - if record_task.file_name in self.list_record_task_and_launch: self.lock_for_list.release() return False, 'There is already a recording task with the same name.' - # start roslaunch uuid = roslaunch.rlutil.get_or_generate_uuid(None, False) - roslaunch_path = rospkg.RosPack().get_path('audio_video_recorder_server') +\ - '/launch/audio_video_recorder.launch' - roslaunch_cli_args = [ - roslaunch_path, - 'audio_topic_name:={}'.format(record_task.audio_topic_name). + roslaunch_path = rospkg.RosPack().get_path('audio_video_recorder_server') + '/launch/audio_video_recorder.launch.xml' + roslaunch_args = [ \ + 'audio_topic_name:={}'.format(record_task.audio_topic_name), 'image_topic_name:={}'.format(record_task.image_topic_name), 'queue_size:={}'.format(record_task.queue_size), 'file_name:={}'.format(record_task.flie_name), @@ -61,15 +53,22 @@ def __start_record(self, record_task): 'audio_format:={}'.format(record_task.audio_format), 'audio_sample_format:={}'.format(record_task.audio_sample_format), 'audio_channels:={}'.format(record_task.audio_channels), + 'audio_depth:={}'.format(record_task.audio_depth), + 'audio_sample_rate:={}'.format(record_task.audio_sample_rate), + 'video_encoding:={}'.format(record_task.video_encoding), + 'video_height:={}'.format(record_task.video_height), + 'video_width:={}'.format(record_task.video_width), + 'video_framerate:={}'.format(record_task.video_framerate) ] - roslaunch_file = roslaunch.rlutil.resolve_launch_arguments( - roslaunch_cli_args) + roslaunch_file = [( + roslaunch.rlutil.resolve_launch_arguments([roslaunch_path])[0], + roslaunch_cli_args)] roslaunch_parent = roslaunch.parent.ROSLaunchParent( uuid, - roslaunch_file + roslaunch_file, + is_core=False ) roslaunch_parent.start() - # Add task to list self.list_record_task_and_launch[record_task.file_name] = { 'task': record_task, @@ -79,16 +78,38 @@ def __start_record(self, record_task): self.lock_for_list.release() return True, 'Success' + def __stop_record(self, file_name): + + if not isinstance(file_name, str): + return False, 'Argument is not an instance of str' + self.lock_for_list.acquire() + if file_name not in self.list_record_task_and_launch: + self.lock_for_list.release() + return False, 'There is no recording task with the specified name.' + self.list_record_task_and_launch[file_name]['launch_handler'].shutdown() + del self.list_record_task_and_launch[file_name] + self.lock_for_list.release() + return True, 'Success' + def handler_start_record(self, req): - uuid = roslaunch.rlutil.get_or_generate_uuid(None, False) - roslaunch_path = rospkg.RosPack().get_path('audio_video_recorder_server') +\ - '/launch/audio_video_recorder.launch' - roslaunch_cli_args = [roslaunch_path] - roslaunch_file = roslaunch.rlutil.resolve_launch_arguments( - roslaunch_cli_args) - self.roslaunch_parent = roslaunch.parent.ROSLaunchParent( - uuid, - roslaunch_file - ) - self.roslaunch_parent.start() + success, message = self.__start_record(req.task) + response = StartRecordResponse() + response.success = success + response.message = message + return response + + def handler_stop_record(self, req): + + success, message = self.__stop_record(req.file_name) + response = StopRecordResponse() + response.success = success + response.message = message + return response + + def spin(self): + + rate = rospy.Rate(1) + while not rospy.is_shutdown(): + rate.sleep() + self.__publish_tasks() From c2cb8a386384b2697f56f8d712063cc3064048e4 Mon Sep 17 00:00:00 2001 From: Koki Shinjo Date: Fri, 5 Nov 2021 17:11:16 +0900 Subject: [PATCH 03/12] [audio_video_recorder_server] fix bugs and add demo --- .../launch/demo.launch | 37 ++++++++ .../msg/RecordTask.msg | 12 +-- .../node_scripts/client_demo.py | 33 +++++++ .../audio_video_recorder_server.py | 13 ++- .../libaudio_video_recorder_server.py | 88 +++++++++++++++++++ 5 files changed, 175 insertions(+), 8 deletions(-) create mode 100644 audio_video_recorder_server/launch/demo.launch create mode 100755 audio_video_recorder_server/node_scripts/client_demo.py create mode 100644 audio_video_recorder_server/src/audio_video_recorder_server/libaudio_video_recorder_server.py diff --git a/audio_video_recorder_server/launch/demo.launch b/audio_video_recorder_server/launch/demo.launch new file mode 100644 index 000000000..45752b55e --- /dev/null +++ b/audio_video_recorder_server/launch/demo.launch @@ -0,0 +1,37 @@ + + + + bitrate: 128 + device: "" + channels: 1 + sample_rate: 16000 + format: mp3 + sample_format: S16LE + + + + + + pixel_format: yuyv + image_height: 480 + image_width: 640 + framerate: 30 + + + + + + + + diff --git a/audio_video_recorder_server/msg/RecordTask.msg b/audio_video_recorder_server/msg/RecordTask.msg index c78a40527..05f22ac8e 100644 --- a/audio_video_recorder_server/msg/RecordTask.msg +++ b/audio_video_recorder_server/msg/RecordTask.msg @@ -5,10 +5,10 @@ string file_name # This will be used as key string file_format string audio_format string audio_sample_format -string audio_channels -string audio_depth -string audio_sample_rate +int32 audio_channels +int32 audio_depth +int32 audio_sample_rate string video_encoding -string video_height -string video_width -string video_framerate +int32 video_height +int32 video_width +int32 video_framerate diff --git a/audio_video_recorder_server/node_scripts/client_demo.py b/audio_video_recorder_server/node_scripts/client_demo.py new file mode 100755 index 000000000..88fbc8981 --- /dev/null +++ b/audio_video_recorder_server/node_scripts/client_demo.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python +# -*- encoding: utf-8 -*- + +import rospy +from audio_video_recorder_server.libaudio_video_recorder_server import AudioVideoRecorderClient +from sensor_msgs.msg import Image +from audio_common_msgs.msg import AudioData + + +def main(): + + rospy.init_node('audio_video_recorder_client_demo') + + destination = rospy.get_param('~destination','/tmp/') + file_name = destination + 'audio_video_recorder_server_demo.avi' + + try: + msg_image = rospy.wait_for_message('/usb_cam_node/image_raw', Image, timeout=rospy.Duration(10)) + msg_audio = rospy.wait_for_message('/audio', AudioData, timeout=rospy.Duration(10)) + except rospy.ROSException as e: + rospy.logerr(e) + return + + client = AudioVideoRecorderClient() + rospy.loginfo('Start recording') + client.start_record('/audio','/usb_cam_node/image_raw',file_name,30) + rospy.sleep(10) + rospy.loginfo('Stop recording') + client.stop_record(file_name) + + +if __name__ == '__main__': + main() diff --git a/audio_video_recorder_server/src/audio_video_recorder_server/audio_video_recorder_server.py b/audio_video_recorder_server/src/audio_video_recorder_server/audio_video_recorder_server.py index bd9887ea7..2b1584f3b 100644 --- a/audio_video_recorder_server/src/audio_video_recorder_server/audio_video_recorder_server.py +++ b/audio_video_recorder_server/src/audio_video_recorder_server/audio_video_recorder_server.py @@ -1,6 +1,7 @@ # -*- encoding: utf-8 -*- import rospy +import rospkg import roslaunch from .msg import RecordTask, RecordTaskArray @@ -48,7 +49,7 @@ def __start_record(self, record_task): 'audio_topic_name:={}'.format(record_task.audio_topic_name), 'image_topic_name:={}'.format(record_task.image_topic_name), 'queue_size:={}'.format(record_task.queue_size), - 'file_name:={}'.format(record_task.flie_name), + 'file_name:={}'.format(record_task.file_name), 'file_format:={}'.format(record_task.file_format), 'audio_format:={}'.format(record_task.audio_format), 'audio_sample_format:={}'.format(record_task.audio_sample_format), @@ -62,7 +63,7 @@ def __start_record(self, record_task): ] roslaunch_file = [( roslaunch.rlutil.resolve_launch_arguments([roslaunch_path])[0], - roslaunch_cli_args)] + roslaunch_args)] roslaunch_parent = roslaunch.parent.ROSLaunchParent( uuid, roslaunch_file, @@ -94,6 +95,10 @@ def __stop_record(self, file_name): def handler_start_record(self, req): success, message = self.__start_record(req.task) + if success: + rospy.loginfo('Start recoding to {}: {}'.format(req.task.file_name, message)) + else: + rospy.logerr('Failed to start recoding to {}: {}'.format(req.task.file_name, message)) response = StartRecordResponse() response.success = success response.message = message @@ -102,6 +107,10 @@ def handler_start_record(self, req): def handler_stop_record(self, req): success, message = self.__stop_record(req.file_name) + if success: + rospy.loginfo('Stop recoding to {}: {}'.format(req.file_name, message)) + else: + rospy.logerr('Failed to stop recoding to {}: {}'.format(req.file_name, message)) response = StopRecordResponse() response.success = success response.message = message diff --git a/audio_video_recorder_server/src/audio_video_recorder_server/libaudio_video_recorder_server.py b/audio_video_recorder_server/src/audio_video_recorder_server/libaudio_video_recorder_server.py new file mode 100644 index 000000000..59ca5cee1 --- /dev/null +++ b/audio_video_recorder_server/src/audio_video_recorder_server/libaudio_video_recorder_server.py @@ -0,0 +1,88 @@ +# -*- encoding: utf-8 -*- + +import rospy +import roslaunch + +from sensor_msgs.msg import Image +from .msg import RecordTask, RecordTaskArray +from .srv import StartRecord, StartRecordRequest, StartRecordResponse +from .srv import StopRecord, StopRecordRequest, StopRecordResponse + +import threading + + +class AudioVideoRecorderClient: + + def __init__(self): + + self.record_task_array = RecordTaskArray() + + self.client_start_record = rospy.ServiceProxy( + '/audio_video_recorder_server/start_record', + StartRecord) + self.client_stop_record = rospy.ServiceProxy( + '/audio_video_recorder_server/stop_record', + StopRecord) + self.sub_record_task_array = rospy.Subscriber( + '/audio_video_recorder_server/record_tasks', + RecordTaskArray, + self.__callback + ) + + def __callback(self, msg): + self.record_task_array = msg + + def start_record(self, + audio_topic_name, + image_topic_name, + file_name, + video_framerate, + queue_size=100, + file_format='avi', + audio_format='mp3', + audio_sample_format='S16LE', + audio_channels=1, + audio_depth=16, + audio_sample_rate=16000, + video_encoding='RGB', + video_height=None, + video_width=None + ): + # Get width and height from message + if video_height is None or video_width is None: + try: + msg_image = rospy.wait_for_message(image_topic_name,Image,timeout=rospy.Duration(5)) + video_height = msg_image.height + video_width = msg_image.width + except rospy.ROSException as e: + return False, 'Image topic not published.' + # + req = StartRecordRequest() + req.task.audio_topic_name = audio_topic_name + req.task.image_topic_name = image_topic_name + req.task.queue_size = queue_size + req.task.file_name = file_name + req.task.file_format = file_format + req.task.audio_format = audio_format + req.task.audio_sample_format = audio_sample_format + req.task.audio_channels = audio_channels + req.task.audio_depth = audio_depth + req.task.audio_sample_rate = audio_sample_rate + req.task.video_encoding = video_encoding + req.task.video_height = video_height + req.task.video_width = video_width + req.task.video_framerate = video_framerate + # + res = self.client_start_record(req) + return res.success, res.message + + def get_record_task_array(self): + return self.record_task_array + + def stop_record(self, file_name): + # + req = StopRecordRequest() + req.file_name = file_name + # + res = self.client_stop_record(req) + return res.success, res.message From 5e43c718b29633e8610f08b7d28102a12faa67c8 Mon Sep 17 00:00:00 2001 From: Koki Shinjo Date: Fri, 5 Nov 2021 17:24:25 +0900 Subject: [PATCH 04/12] [audio_video_recorder_server] add README --- audio_video_recorder_server/README.md | 36 +++++++++++++++++++ .../node_scripts/client_demo.py | 13 ++++--- 2 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 audio_video_recorder_server/README.md diff --git a/audio_video_recorder_server/README.md b/audio_video_recorder_server/README.md new file mode 100644 index 000000000..c60dced52 --- /dev/null +++ b/audio_video_recorder_server/README.md @@ -0,0 +1,36 @@ +# Audio Video Recorder Server + +This package provides ROS Topic/Service Interface to [audio_video_recorder](../audio_video_recorder) and python client library. + +## How to use demo + +`demo.launch` shows how to use this package. +Before launching, please make sure your PC has a usb camera and a microphone. + +``` +roslaunch audio_video_recorder_server demo.launch +``` + +This launch will launch `audio_video_recorder_server` node and an example client node with `AudioVideoRecoderClient` instance. The client script will start 2 recording tasks simultaneously, and after finishing, there will be 2 output video files. (`/tmp/audio_video_recorder_server_demo_02.avi` and `/tmp/audio_video_recorder_server_demo_02.avi`) + +See [demo.launch](./launch/demo.launch) and [client_demo.py](./node_scripts/client_demo.py) for details. + +## Node + +### audio_video_recorder_server + +#### Services + +- `~start_record` (type: `audio_video_recorder_server/StartRecord`) + +Start a recording task. + +- `~stop_record` (type: `audio_video_recorder_server/StopRecord`) + +Stop an specified recoding task. + +#### Topics + +- `~record_tasks` (type: `audio_video_recorder_server/RecordTaskArray) + + Recoding tasks currently running. diff --git a/audio_video_recorder_server/node_scripts/client_demo.py b/audio_video_recorder_server/node_scripts/client_demo.py index 88fbc8981..6dfe2d54a 100755 --- a/audio_video_recorder_server/node_scripts/client_demo.py +++ b/audio_video_recorder_server/node_scripts/client_demo.py @@ -12,7 +12,8 @@ def main(): rospy.init_node('audio_video_recorder_client_demo') destination = rospy.get_param('~destination','/tmp/') - file_name = destination + 'audio_video_recorder_server_demo.avi' + file_name_01 = destination + 'audio_video_recorder_server_demo_01.avi' + file_name_02 = destination + 'audio_video_recorder_server_demo_02.avi' try: msg_image = rospy.wait_for_message('/usb_cam_node/image_raw', Image, timeout=rospy.Duration(10)) @@ -23,10 +24,14 @@ def main(): client = AudioVideoRecorderClient() rospy.loginfo('Start recording') - client.start_record('/audio','/usb_cam_node/image_raw',file_name,30) - rospy.sleep(10) + client.start_record('/audio','/usb_cam_node/image_raw',file_name_01,30) + rospy.sleep(5) + client.start_record('/audio','/usb_cam_node/image_raw',file_name_02,30) + rospy.sleep(5) rospy.loginfo('Stop recording') - client.stop_record(file_name) + client.stop_record(file_name_01) + rospy.sleep(5) + client.stop_record(file_name_02) if __name__ == '__main__': From 7b636f429a6d22955128c95fdb1c157aad72e72a Mon Sep 17 00:00:00 2001 From: Koki Shinjo Date: Sun, 7 Nov 2021 14:22:07 +0900 Subject: [PATCH 05/12] [audio_video_recorder] make node name of audio_video_recorder anounymous --- audio_video_recorder/launch/audio_video_recorder.launch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/audio_video_recorder/launch/audio_video_recorder.launch b/audio_video_recorder/launch/audio_video_recorder.launch index 24098b219..e135b0f32 100644 --- a/audio_video_recorder/launch/audio_video_recorder.launch +++ b/audio_video_recorder/launch/audio_video_recorder.launch @@ -13,7 +13,7 @@ - From 163e42d21c3f6e026956d8d5b7147987b6059689 Mon Sep 17 00:00:00 2001 From: Koki Shinjo Date: Sun, 7 Nov 2021 14:38:46 +0900 Subject: [PATCH 06/12] [audio_video_recorder][audio_video_recorder_server] merge audio_video_recorder_server to audio_video_recorder --- audio_video_recorder/CMakeLists.txt | 26 +++++++++++++- .../launch/audio_video_recorder_server.launch | 2 +- .../msg/RecordTask.msg | 0 audio_video_recorder/msg/RecordTaskArray.msg | 1 + .../node_scripts/audio_video_recorder_server | 2 +- audio_video_recorder/package.xml | 5 +++ .../sample_audio_video_recorder_client.py | 2 +- .../sample_audio_video_recorder_server.launch | 8 ++--- .../setup.py | 2 +- .../src/audio_video_recorder}/__init__.py | 0 .../audio_video_recorder_client.py | 0 .../audio_video_recorder_server.py | 2 +- audio_video_recorder/srv/StartRecord.srv | 4 +++ .../srv/StopRecord.srv | 0 .../launch/audio_video_recorder.launch.xml | 34 ------------------- .../msg/RecordTaskArray.msg | 1 - .../srv/StartRecord.srv | 4 --- 17 files changed, 44 insertions(+), 49 deletions(-) rename {audio_video_recorder_server => audio_video_recorder}/launch/audio_video_recorder_server.launch (74%) rename {audio_video_recorder_server => audio_video_recorder}/msg/RecordTask.msg (100%) create mode 100644 audio_video_recorder/msg/RecordTaskArray.msg rename {audio_video_recorder_server => audio_video_recorder}/node_scripts/audio_video_recorder_server (70%) rename audio_video_recorder_server/node_scripts/client_demo.py => audio_video_recorder/sample/sample_audio_video_recorder_client.py (92%) rename audio_video_recorder_server/launch/demo.launch => audio_video_recorder/sample/sample_audio_video_recorder_server.launch (82%) rename {audio_video_recorder_server => audio_video_recorder}/setup.py (79%) rename {audio_video_recorder_server/src/audio_video_recorder_server => audio_video_recorder/src/audio_video_recorder}/__init__.py (100%) rename audio_video_recorder_server/src/audio_video_recorder_server/libaudio_video_recorder_server.py => audio_video_recorder/src/audio_video_recorder/audio_video_recorder_client.py (100%) rename {audio_video_recorder_server/src/audio_video_recorder_server => audio_video_recorder/src/audio_video_recorder}/audio_video_recorder_server.py (98%) create mode 100644 audio_video_recorder/srv/StartRecord.srv rename {audio_video_recorder_server => audio_video_recorder}/srv/StopRecord.srv (100%) delete mode 100644 audio_video_recorder_server/launch/audio_video_recorder.launch.xml delete mode 100644 audio_video_recorder_server/msg/RecordTaskArray.msg delete mode 100644 audio_video_recorder_server/srv/StartRecord.srv diff --git a/audio_video_recorder/CMakeLists.txt b/audio_video_recorder/CMakeLists.txt index 626236ba8..fcfadd415 100644 --- a/audio_video_recorder/CMakeLists.txt +++ b/audio_video_recorder/CMakeLists.txt @@ -2,13 +2,37 @@ cmake_minimum_required(VERSION 2.8.3) project(audio_video_recorder) -find_package(catkin REQUIRED COMPONENTS roscpp audio_common_msgs sensor_msgs) +find_package(catkin REQUIRED COMPONENTS + roscpp + rospy + audio_common_msgs + message_generation + sensor_msgs +) find_package(PkgConfig) pkg_check_modules(GST1.0 gstreamer-1.0 REQUIRED) find_package(Boost REQUIRED COMPONENTS thread) +catkin_python_setup() + +add_message_files( + FILES + RecordTask.msg + RecordTaskArray.msg +) + +add_service_files( + FILES + StartRecord.srv + StopRecord.srv +) + +generate_messages( + DEPENDENCIES +) + catkin_package( INCLUDE_DIRS include CATKIN_DEPENDS diff --git a/audio_video_recorder_server/launch/audio_video_recorder_server.launch b/audio_video_recorder/launch/audio_video_recorder_server.launch similarity index 74% rename from audio_video_recorder_server/launch/audio_video_recorder_server.launch rename to audio_video_recorder/launch/audio_video_recorder_server.launch index 95a01e53c..879055f46 100644 --- a/audio_video_recorder_server/launch/audio_video_recorder_server.launch +++ b/audio_video_recorder/launch/audio_video_recorder_server.launch @@ -1,6 +1,6 @@ diff --git a/audio_video_recorder_server/msg/RecordTask.msg b/audio_video_recorder/msg/RecordTask.msg similarity index 100% rename from audio_video_recorder_server/msg/RecordTask.msg rename to audio_video_recorder/msg/RecordTask.msg diff --git a/audio_video_recorder/msg/RecordTaskArray.msg b/audio_video_recorder/msg/RecordTaskArray.msg new file mode 100644 index 000000000..3124aa061 --- /dev/null +++ b/audio_video_recorder/msg/RecordTaskArray.msg @@ -0,0 +1 @@ +audio_video_recorder/RecordTask[] array diff --git a/audio_video_recorder_server/node_scripts/audio_video_recorder_server b/audio_video_recorder/node_scripts/audio_video_recorder_server similarity index 70% rename from audio_video_recorder_server/node_scripts/audio_video_recorder_server rename to audio_video_recorder/node_scripts/audio_video_recorder_server index c50ad42b9..d7ec3dcf6 100755 --- a/audio_video_recorder_server/node_scripts/audio_video_recorder_server +++ b/audio_video_recorder/node_scripts/audio_video_recorder_server @@ -2,7 +2,7 @@ # -*- encoding: utf-8 -*- import rospy -from audio_video_recorder_server.audio_video_recorder_server import AudioVideoRecorderServer +from audio_video_recorder.audio_video_recorder_server import AudioVideoRecorderServer def main(): diff --git a/audio_video_recorder/package.xml b/audio_video_recorder/package.xml index ac5b7a282..06118f24b 100644 --- a/audio_video_recorder/package.xml +++ b/audio_video_recorder/package.xml @@ -12,18 +12,23 @@ catkin roscpp + rospy audio_common_msgs libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev message_filters + message_generation sensor_msgs roscpp + roslaunch + rospy audio_common_msgs gstreamer1.0 gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-ugly message_filters + message_runtime sensor_msgs diff --git a/audio_video_recorder_server/node_scripts/client_demo.py b/audio_video_recorder/sample/sample_audio_video_recorder_client.py similarity index 92% rename from audio_video_recorder_server/node_scripts/client_demo.py rename to audio_video_recorder/sample/sample_audio_video_recorder_client.py index 6dfe2d54a..3e12bfb94 100755 --- a/audio_video_recorder_server/node_scripts/client_demo.py +++ b/audio_video_recorder/sample/sample_audio_video_recorder_client.py @@ -2,7 +2,7 @@ # -*- encoding: utf-8 -*- import rospy -from audio_video_recorder_server.libaudio_video_recorder_server import AudioVideoRecorderClient +from audio_video_recorder.audio_video_recorder_client import AudioVideoRecorderClient from sensor_msgs.msg import Image from audio_common_msgs.msg import AudioData diff --git a/audio_video_recorder_server/launch/demo.launch b/audio_video_recorder/sample/sample_audio_video_recorder_server.launch similarity index 82% rename from audio_video_recorder_server/launch/demo.launch rename to audio_video_recorder/sample/sample_audio_video_recorder_server.launch index 45752b55e..ec28406db 100644 --- a/audio_video_recorder_server/launch/demo.launch +++ b/audio_video_recorder/sample/sample_audio_video_recorder_server.launch @@ -20,16 +20,16 @@ diff --git a/audio_video_recorder_server/setup.py b/audio_video_recorder/setup.py similarity index 79% rename from audio_video_recorder_server/setup.py rename to audio_video_recorder/setup.py index d2517a85d..52605f4d2 100644 --- a/audio_video_recorder_server/setup.py +++ b/audio_video_recorder/setup.py @@ -2,7 +2,7 @@ from catkin_pkg.python_setup import generate_distutils_setup d = generate_distutils_setup( - packages=['audio_video_recorder_server'], + packages=['audio_video_recorder'], scripts=[], package_dir={'': 'src'} ) diff --git a/audio_video_recorder_server/src/audio_video_recorder_server/__init__.py b/audio_video_recorder/src/audio_video_recorder/__init__.py similarity index 100% rename from audio_video_recorder_server/src/audio_video_recorder_server/__init__.py rename to audio_video_recorder/src/audio_video_recorder/__init__.py diff --git a/audio_video_recorder_server/src/audio_video_recorder_server/libaudio_video_recorder_server.py b/audio_video_recorder/src/audio_video_recorder/audio_video_recorder_client.py similarity index 100% rename from audio_video_recorder_server/src/audio_video_recorder_server/libaudio_video_recorder_server.py rename to audio_video_recorder/src/audio_video_recorder/audio_video_recorder_client.py diff --git a/audio_video_recorder_server/src/audio_video_recorder_server/audio_video_recorder_server.py b/audio_video_recorder/src/audio_video_recorder/audio_video_recorder_server.py similarity index 98% rename from audio_video_recorder_server/src/audio_video_recorder_server/audio_video_recorder_server.py rename to audio_video_recorder/src/audio_video_recorder/audio_video_recorder_server.py index 2b1584f3b..30906143d 100644 --- a/audio_video_recorder_server/src/audio_video_recorder_server/audio_video_recorder_server.py +++ b/audio_video_recorder/src/audio_video_recorder/audio_video_recorder_server.py @@ -44,7 +44,7 @@ def __start_record(self, record_task): return False, 'There is already a recording task with the same name.' # start roslaunch uuid = roslaunch.rlutil.get_or_generate_uuid(None, False) - roslaunch_path = rospkg.RosPack().get_path('audio_video_recorder_server') + '/launch/audio_video_recorder.launch.xml' + roslaunch_path = rospkg.RosPack().get_path('audio_video_recorder') + '/launch/audio_video_recorder.launch' roslaunch_args = [ \ 'audio_topic_name:={}'.format(record_task.audio_topic_name), 'image_topic_name:={}'.format(record_task.image_topic_name), diff --git a/audio_video_recorder/srv/StartRecord.srv b/audio_video_recorder/srv/StartRecord.srv new file mode 100644 index 000000000..b0cfd3fe3 --- /dev/null +++ b/audio_video_recorder/srv/StartRecord.srv @@ -0,0 +1,4 @@ +audio_video_recorder/RecordTask task +--- +bool success +string message diff --git a/audio_video_recorder_server/srv/StopRecord.srv b/audio_video_recorder/srv/StopRecord.srv similarity index 100% rename from audio_video_recorder_server/srv/StopRecord.srv rename to audio_video_recorder/srv/StopRecord.srv diff --git a/audio_video_recorder_server/launch/audio_video_recorder.launch.xml b/audio_video_recorder_server/launch/audio_video_recorder.launch.xml deleted file mode 100644 index d7ccad13c..000000000 --- a/audio_video_recorder_server/launch/audio_video_recorder.launch.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - queue_size: $(arg queue_size) - file_name: $(arg file_name) - file_format: $(arg file_format) - audio_channels: $(arg audio_channels) - audio_sample_rate: $(arg audio_sample_rate) - audio_format: $(arg audio_format) - audio_sample_format: $(arg audio_sample_format) - video_height: $(arg video_height) - video_width: $(arg video_width) - video_framerate: $(arg video_framerate) - video_encoding: $(arg video_encoding) - - - diff --git a/audio_video_recorder_server/msg/RecordTaskArray.msg b/audio_video_recorder_server/msg/RecordTaskArray.msg deleted file mode 100644 index f47e6204a..000000000 --- a/audio_video_recorder_server/msg/RecordTaskArray.msg +++ /dev/null @@ -1 +0,0 @@ -audio_video_recorder_server/RecordTask[] array diff --git a/audio_video_recorder_server/srv/StartRecord.srv b/audio_video_recorder_server/srv/StartRecord.srv deleted file mode 100644 index c486a30b6..000000000 --- a/audio_video_recorder_server/srv/StartRecord.srv +++ /dev/null @@ -1,4 +0,0 @@ -audio_video_recorder_server/RecordTask task ---- -bool success -string message From 5e8f8e55c943655e2339cd201a6c206e20ac2fdb Mon Sep 17 00:00:00 2001 From: Koki Shinjo Date: Sun, 7 Nov 2021 14:41:35 +0900 Subject: [PATCH 07/12] [audio_video_recorder] Add installation for node_scripts --- audio_video_recorder/CMakeLists.txt | 3 +++ .../sample_audio_video_recorder_client.py | 0 2 files changed, 3 insertions(+) rename audio_video_recorder/{sample => node_scripts}/sample_audio_video_recorder_client.py (100%) diff --git a/audio_video_recorder/CMakeLists.txt b/audio_video_recorder/CMakeLists.txt index fcfadd415..b748202dc 100644 --- a/audio_video_recorder/CMakeLists.txt +++ b/audio_video_recorder/CMakeLists.txt @@ -52,6 +52,9 @@ add_executable(audio_video_recorder src/audio_video_recorder.cpp) target_link_libraries(audio_video_recorder ${catkin_LIBRARIES} ${GST1.0_LIBRARIES} ${Boost_LIBRARIES}) add_dependencies(audio_video_recorder ${catkin_EXPORTED_TARGETS}) +catkin_install_python(PROGRAMS node_scripts/audio_video_recorder_server node_scripts/sample_audio_video_recorder_client.py + DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}) + install(TARGETS audio_video_recorder DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}) diff --git a/audio_video_recorder/sample/sample_audio_video_recorder_client.py b/audio_video_recorder/node_scripts/sample_audio_video_recorder_client.py similarity index 100% rename from audio_video_recorder/sample/sample_audio_video_recorder_client.py rename to audio_video_recorder/node_scripts/sample_audio_video_recorder_client.py From f4a3ea1f0173e968e85f481292062b34efbd8de6 Mon Sep 17 00:00:00 2001 From: Koki Shinjo Date: Tue, 9 Nov 2021 09:56:08 +0900 Subject: [PATCH 08/12] [audio_video_recorder] update README.md --- audio_video_recorder/README.md | 42 ++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/audio_video_recorder/README.md b/audio_video_recorder/README.md index ab37e48b3..5b2b5a195 100644 --- a/audio_video_recorder/README.md +++ b/audio_video_recorder/README.md @@ -15,11 +15,25 @@ You can record audio and video on your laptop. roslaunch audio_video_recorder sample_audio_video_recorder.launch ``` -## Parameters +If you want to sedd ROS Interface Sample (Topic/Service) of audio_video_recorder, Please run audio_video_recorder_server demo. + +``` +roslaunch audio_video_recorder sample_audio_video_recorder_server.launch +``` + +And if you want to see an example of client script for audio_video_recorder_server. please see [sample_audio_video_recorder_client.py](./node_scripts/sample_audio_video_recorder_client.py). + +## Nodes + +### audio_video_recorder + +Node to record audio and video with given parameters. + +#### Parameters Node: `audio_video_recorder/audio_video_recorder` -### Common parameters +##### Common parameters - `queue_size` (`Int`, default: `100`) @@ -33,7 +47,7 @@ Node: `audio_video_recorder/audio_video_recorder` Output file format (Only `avi` is supported now.) -### Audio parameters +##### Audio parameters - `audio_format` (`String`, default: `mp3`) @@ -55,7 +69,7 @@ Node: `audio_video_recorder/audio_video_recorder` Audio sample rate -### Video parameters +##### Video parameters - `video_encoding` (`String`, default: `RGB`) @@ -72,3 +86,23 @@ Node: `audio_video_recorder/audio_video_recorder` - `video_framerate` (`Int`, default: `30`) Video frame rate + +### audio_video_recorder_server + +ROS Interface and recording task manager for audio_video_recorder. + +#### Services + +- `~start_record` (`audio_video_recorder/StartRecord`) + + Start a recording task + +- `~stop_record` (`audio_video_recorder/StopRecord`) + + Stop a specified recording task + +#### Publisher + +- `~record_tasks` (`audio_video_recorder/RecordTaskArray`) + + Recording tasks currently running. From 3b5928ac342229f95e5d8044929099b3a623f449 Mon Sep 17 00:00:00 2001 From: Koki Shinjo Date: Tue, 9 Nov 2021 12:10:40 +0900 Subject: [PATCH 09/12] [audio_video_recorder_server] remove audio_video_recorder_server package --- audio_video_recorder_server/CMakeLists.txt | 116 --------------------- audio_video_recorder_server/README.md | 36 ------- audio_video_recorder_server/package.xml | 25 ----- 3 files changed, 177 deletions(-) delete mode 100644 audio_video_recorder_server/CMakeLists.txt delete mode 100644 audio_video_recorder_server/README.md delete mode 100644 audio_video_recorder_server/package.xml diff --git a/audio_video_recorder_server/CMakeLists.txt b/audio_video_recorder_server/CMakeLists.txt deleted file mode 100644 index bdacebc8d..000000000 --- a/audio_video_recorder_server/CMakeLists.txt +++ /dev/null @@ -1,116 +0,0 @@ -cmake_minimum_required(VERSION 3.0.2) -project(audio_video_recorder_server) - -find_package(catkin REQUIRED - roscpp - rospy - message_generation -) - -catkin_python_setup() - -add_message_files( - FILES - RecordTask.msg - RecordTaskArray.msg -) - -add_service_files( - FILES - StartRecord.srv - StopRecord.srv -) - -generate_messages( - DEPENDENCIES -) - -catkin_package( - CATKIN_DEPENDS rospy roslaunch -) - - -## Declare a C++ library -# add_library(${PROJECT_NAME} -# src/${PROJECT_NAME}/audio_video_recorder_server.cpp -# ) - -## Add cmake target dependencies of the library -## as an example, code may need to be generated before libraries -## either from message generation or dynamic reconfigure -# add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) - -## Declare a C++ executable -## With catkin_make all packages are built within a single CMake context -## The recommended prefix ensures that target names across packages don't collide -# add_executable(${PROJECT_NAME}_node src/audio_video_recorder_server_node.cpp) - -## Rename C++ executable without prefix -## The above recommended prefix causes long target names, the following renames the -## target back to the shorter version for ease of user use -## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node" -# set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "") - -## Add cmake target dependencies of the executable -## same as for the library above -# add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) - -## Specify libraries to link a library or executable target against -# target_link_libraries(${PROJECT_NAME}_node -# ${catkin_LIBRARIES} -# ) - -############# -## Install ## -############# - -# all install targets should use catkin DESTINATION variables -# See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html - -## Mark executable scripts (Python etc.) for installation -## in contrast to setup.py, you can choose the destination -# catkin_install_python(PROGRAMS -# scripts/my_python_script -# DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} -# ) - -## Mark executables for installation -## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_executables.html -# install(TARGETS ${PROJECT_NAME}_node -# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} -# ) - -## Mark libraries for installation -## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_libraries.html -# install(TARGETS ${PROJECT_NAME} -# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} -# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} -# RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION} -# ) - -## Mark cpp header files for installation -# install(DIRECTORY include/${PROJECT_NAME}/ -# DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} -# FILES_MATCHING PATTERN "*.h" -# PATTERN ".svn" EXCLUDE -# ) - -## Mark other files for installation (e.g. launch and bag files, etc.) -# install(FILES -# # myfile1 -# # myfile2 -# DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} -# ) - -############# -## Testing ## -############# - -## Add gtest based cpp test target and link libraries -# catkin_add_gtest(${PROJECT_NAME}-test test/test_audio_video_recorder_server.cpp) -# if(TARGET ${PROJECT_NAME}-test) -# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME}) -# endif() - -## Add folders to be run by python nosetests -# catkin_add_nosetests(test) diff --git a/audio_video_recorder_server/README.md b/audio_video_recorder_server/README.md deleted file mode 100644 index c60dced52..000000000 --- a/audio_video_recorder_server/README.md +++ /dev/null @@ -1,36 +0,0 @@ -# Audio Video Recorder Server - -This package provides ROS Topic/Service Interface to [audio_video_recorder](../audio_video_recorder) and python client library. - -## How to use demo - -`demo.launch` shows how to use this package. -Before launching, please make sure your PC has a usb camera and a microphone. - -``` -roslaunch audio_video_recorder_server demo.launch -``` - -This launch will launch `audio_video_recorder_server` node and an example client node with `AudioVideoRecoderClient` instance. The client script will start 2 recording tasks simultaneously, and after finishing, there will be 2 output video files. (`/tmp/audio_video_recorder_server_demo_02.avi` and `/tmp/audio_video_recorder_server_demo_02.avi`) - -See [demo.launch](./launch/demo.launch) and [client_demo.py](./node_scripts/client_demo.py) for details. - -## Node - -### audio_video_recorder_server - -#### Services - -- `~start_record` (type: `audio_video_recorder_server/StartRecord`) - -Start a recording task. - -- `~stop_record` (type: `audio_video_recorder_server/StopRecord`) - -Stop an specified recoding task. - -#### Topics - -- `~record_tasks` (type: `audio_video_recorder_server/RecordTaskArray) - - Recoding tasks currently running. diff --git a/audio_video_recorder_server/package.xml b/audio_video_recorder_server/package.xml deleted file mode 100644 index d1051290a..000000000 --- a/audio_video_recorder_server/package.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - audio_video_recorder_server - 0.0.0 - The audio_video_recorder_server package - - Koki Shinjo - Kei Okada - Koki Shinjo - - BSD - - catkin - - roscpp - rospy - message_generation - audio_video_recorder - message_runtime - roslaunch - rospy - - - - From 5a6071d1e9e9fa0fa466b8deb7e965e97c37b198 Mon Sep 17 00:00:00 2001 From: Koki Shinjo Date: Wed, 10 Nov 2021 13:23:10 +0900 Subject: [PATCH 10/12] [audio_video_recorder] fix module import --- .../src/audio_video_recorder/audio_video_recorder_client.py | 6 +++--- .../src/audio_video_recorder/audio_video_recorder_server.py | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/audio_video_recorder/src/audio_video_recorder/audio_video_recorder_client.py b/audio_video_recorder/src/audio_video_recorder/audio_video_recorder_client.py index 59ca5cee1..a0dd48ccb 100644 --- a/audio_video_recorder/src/audio_video_recorder/audio_video_recorder_client.py +++ b/audio_video_recorder/src/audio_video_recorder/audio_video_recorder_client.py @@ -4,9 +4,9 @@ import roslaunch from sensor_msgs.msg import Image -from .msg import RecordTask, RecordTaskArray -from .srv import StartRecord, StartRecordRequest, StartRecordResponse -from .srv import StopRecord, StopRecordRequest, StopRecordResponse +from audio_video_recorder.msg import RecordTask, RecordTaskArray +from audio_video_recorder.srv import StartRecord, StartRecordRequest, StartRecordResponse +from audio_video_recorder.srv import StopRecord, StopRecordRequest, StopRecordResponse import threading diff --git a/audio_video_recorder/src/audio_video_recorder/audio_video_recorder_server.py b/audio_video_recorder/src/audio_video_recorder/audio_video_recorder_server.py index 30906143d..e81b9b4f9 100644 --- a/audio_video_recorder/src/audio_video_recorder/audio_video_recorder_server.py +++ b/audio_video_recorder/src/audio_video_recorder/audio_video_recorder_server.py @@ -4,9 +4,9 @@ import rospkg import roslaunch -from .msg import RecordTask, RecordTaskArray -from .srv import StartRecord, StartRecordRequest, StartRecordResponse -from .srv import StopRecord, StopRecordRequest, StopRecordResponse +from audio_video_recorder.msg import RecordTask, RecordTaskArray +from audio_video_recorder.srv import StartRecord, StartRecordRequest, StartRecordResponse +from audio_video_recorder.srv import StopRecord, StopRecordRequest, StopRecordResponse import threading From a4de30b247106275babb8cef0769c5fc1dfb2824 Mon Sep 17 00:00:00 2001 From: Koki Shinjo Date: Sun, 28 Nov 2021 23:13:59 +0900 Subject: [PATCH 11/12] [audio_video_recorder] add euslisp client --- .../euslisp/audio-video-recorder-client.l | 76 +++++++++++++++++++ .../sample-audio-video-recorder-client.l | 38 ++++++++++ .../sample_audio_video_recorder_client.py | 11 ++- ...o_video_recorder_server_with_roseus.launch | 37 +++++++++ 4 files changed, 159 insertions(+), 3 deletions(-) create mode 100644 audio_video_recorder/euslisp/audio-video-recorder-client.l create mode 100755 audio_video_recorder/euslisp/sample-audio-video-recorder-client.l create mode 100644 audio_video_recorder/sample/sample_audio_video_recorder_server_with_roseus.launch diff --git a/audio_video_recorder/euslisp/audio-video-recorder-client.l b/audio_video_recorder/euslisp/audio-video-recorder-client.l new file mode 100644 index 000000000..20fb33114 --- /dev/null +++ b/audio_video_recorder/euslisp/audio-video-recorder-client.l @@ -0,0 +1,76 @@ +(ros::load-ros-manifest "audio_video_recorder") +(ros::load-ros-manifest "sensor_msgs") + + +(defun call-start-record-service + (audio-topic-name + image-topic-name + file-name + video-framerate + &key + (queue-size 100) + (file-format "avi") + (audio-format "mp3") + (audio-sample-format "S16LE") + (audio-channels 1) + (audio-depth 16) + (audio-sample-rate 16000) + (video-encoding "RGB") + (video-height nil) + (video-width nil)) + (let (msg req res) + (if (or (not video-height) (not video-width)) + (progn + (setq msg (one-shot-subscribe image-topic-name sensor_msgs::Image :timeout 5000)) + (if (not msg) + (progn + (ros::ros-error "Image is not published from ~A" image-topic-name) + (return-from call-start-record-service nil))) + (setq video-height (send msg :height)) + (setq video-width (send msg :width)))) + (setq req (instance audio_video_recorder::StartRecordRequest :init)) + (send req :task :audio_topic_name audio-topic-name) + (send req :task :image_topic_name image-topic-name) + (send req :task :queue_size queue-size) + (send req :task :file_name file-name) + (send req :task :file_format file-format) + (send req :task :audio_format audio-format) + (send req :task :audio_sample_format audio-sample-format) + (send req :task :audio_channels audio-channels) + (send req :task :audio_depth audio-depth) + (send req :task :audio_sample_rate audio-sample-rate) + (send req :task :video_encoding video-encoding) + (send req :task :video_height video-height) + (send req :task :video_width video-width) + (send req :task :video_framerate video-framerate) + (setq res (ros::service-call "/audio_video_recorder_server/start_record" req t)) + (if (not (send res :success)) + (progn + (ros::ros-error "Failed to start recording: ~A" (send res :message)) + (return-from call-start-record-service nil))) + (send res :success) + )) + +(defun call-stop-record-service + (file-name) + (let (req res) + (setq req (instance audio_video_recorder::StopRecordRequest :init)) + (send req :file_name file-name) + (setq res (ros::service-call "/audio_video_recorder_server/stop_record" req t)) + (if (not (send res :success)) + (progn + (ros::ros-error "Failed to stop recording: ~A" (send res :message)) + (return-from call-stop-record-service nil))) + (send res :success) + )) + +(defun get-recording-task-array + () + (let (msg) + (setq msg (one-shot-subscribe "/audio_video_recorder_server/record_tasks" audio_video_recorder::RecordTaskArray :timeout 10000)) + (if (not msg) + (progn + (ros::ros-error "Failed to get a task array message.") + (return-from get-recording-task-array nil))) + (send msg :array) + )) diff --git a/audio_video_recorder/euslisp/sample-audio-video-recorder-client.l b/audio_video_recorder/euslisp/sample-audio-video-recorder-client.l new file mode 100755 index 000000000..23f35b957 --- /dev/null +++ b/audio_video_recorder/euslisp/sample-audio-video-recorder-client.l @@ -0,0 +1,38 @@ +#!/usr/bin/env roseus + +(ros::load-ros-manifest "sensor_msgs") +(ros::load-ros-manifest "audio_common_msgs") + +(load "package://audio_video_recorder/euslisp/audio-video-recorder-client.l") + +(ros::roseus "audio_video_recorder_client_demo") + +(setq destination (ros::get-param "~destination" "/tmp/")) +(setq file-name-01 (concatenate string destination "audio_video_recorder_server_demo_01.avi")) +(setq file-name-02 (concatenate string destination "audio_video_recorder_server_demo_02.avi")) + +(setq msg-image (one-shot-subscribe "/usb_cam_node/image_raw" sensor_msgs::Image :timeout 10000)) +(setq msg-audio (one-shot-subscribe "/audio" audio_common_msgs::AudioData :timeout 10000)) + +(if (or (not msg-image) (not msg-audio)) + (progn + (ros::ros-error "Failed to get image or audio message") + (exit 1))) + +(ros::ros-info "Start a recording task") +(call-start-record-service "/audio" "/usb_cam_node/image_raw" file-name-01 30) +(unix::sleep 5) +(ros::ros-info "Start another recording task") +(call-start-record-service "/audio" "/usb_cam_node/image_raw" file-name-02 30) +(unix::sleep 2) +(ros::ros-info "Get a recording task array") +(setq task-array (get-recording-task-array)) +(ros::ros-info " : ~A" task-array) +(unix::sleep 3) +(ros::ros-info "Stopped the first recording task.") +(call-stop-record-service file-name-01) +(unix::sleep 5) +(ros::ros-info "Stopped the second recording task.") +(call-stop-record-service file-name-02) + +(exit 0) diff --git a/audio_video_recorder/node_scripts/sample_audio_video_recorder_client.py b/audio_video_recorder/node_scripts/sample_audio_video_recorder_client.py index 3e12bfb94..aab950ef7 100755 --- a/audio_video_recorder/node_scripts/sample_audio_video_recorder_client.py +++ b/audio_video_recorder/node_scripts/sample_audio_video_recorder_client.py @@ -23,14 +23,19 @@ def main(): return client = AudioVideoRecorderClient() - rospy.loginfo('Start recording') + rospy.loginfo('Start a recording task') client.start_record('/audio','/usb_cam_node/image_raw',file_name_01,30) rospy.sleep(5) + rospy.loginfo('Start another recording task') client.start_record('/audio','/usb_cam_node/image_raw',file_name_02,30) - rospy.sleep(5) - rospy.loginfo('Stop recording') + rospy.sleep(2) + task_array = client.get_record_task_array() + rospy.loginfo('Get a recording task array : {}'.format(task_array)) + rospy.sleep(3) + rospy.loginfo('Stop the first recording task') client.stop_record(file_name_01) rospy.sleep(5) + rospy.loginfo('Stop the second recording task') client.stop_record(file_name_02) diff --git a/audio_video_recorder/sample/sample_audio_video_recorder_server_with_roseus.launch b/audio_video_recorder/sample/sample_audio_video_recorder_server_with_roseus.launch new file mode 100644 index 000000000..4ab25ec44 --- /dev/null +++ b/audio_video_recorder/sample/sample_audio_video_recorder_server_with_roseus.launch @@ -0,0 +1,37 @@ + + + + bitrate: 128 + device: "" + channels: 1 + sample_rate: 16000 + format: mp3 + sample_format: S16LE + + + + + + pixel_format: yuyv + image_height: 480 + image_width: 640 + framerate: 30 + + + + + + + + From e2852225a8199fb57066e7048b986a0cf98da895 Mon Sep 17 00:00:00 2001 From: Koki Shinjo Date: Sun, 28 Nov 2021 23:14:38 +0900 Subject: [PATCH 12/12] [audio_video_recorder] update CMakeLists.txt --- audio_video_recorder/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/audio_video_recorder/CMakeLists.txt b/audio_video_recorder/CMakeLists.txt index b748202dc..f2e2d2447 100644 --- a/audio_video_recorder/CMakeLists.txt +++ b/audio_video_recorder/CMakeLists.txt @@ -58,5 +58,5 @@ catkin_install_python(PROGRAMS node_scripts/audio_video_recorder_server node_scr install(TARGETS audio_video_recorder DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}) -install(DIRECTORY launch sample +install(DIRECTORY launch sample euslisp DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION})