Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding mongodb based video player #75

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions mongodb_video_player/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
cmake_minimum_required(VERSION 2.8.3)
project(mongodb_video_player)

## Find catkin macros and libraries
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
## is used, also find other catkin packages
find_package(catkin REQUIRED COMPONENTS
message_generation
cv_bridge
rospy
mongodb_media_server
sensor_msgs
std_msgs
)

################################################
## Declare ROS messages, services and actions ##
################################################

## Generate services in the 'srv' folder
add_service_files(
FILES
VideoPlayerService.srv
)

## Generate added messages and services with any dependencies listed here
generate_messages(
DEPENDENCIES
std_msgs
)

###################################
## catkin specific configuration ##
###################################
catkin_package()

#############
## Install ##
#############

install(PROGRAMS
scripts/video_server.py
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
31 changes: 31 additions & 0 deletions mongodb_video_player/package.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?xml version="1.0"?>
<package>
<name>mongodb_video_player</name>
<version>0.0.17</version>
<description>The video_player package</description>

<maintainer email="[email protected]">Christian Dondrup</maintainer>

<license>MIT</license>

<url type="website">https://github.com/strands-project/strands_ui</url>

<author email="[email protected]">Christian Dondrup</author>

<buildtool_depend>catkin</buildtool_depend>
<build_depend>message_generation</build_depend>
<build_depend>cv_bridge</build_depend>
<build_depend>mongodb_media_server</build_depend>
<build_depend>rospy</build_depend>
<build_depend>sensor_msgs</build_depend>
<build_depend>std_msgs</build_depend>
<run_depend>message_runtime</run_depend>
<run_depend>cv_bridge</run_depend>
<run_depend>mongodb_media_server</run_depend>
<run_depend>rospy</run_depend>
<run_depend>sensor_msgs</run_depend>
<run_depend>std_msgs</run_depend>


<export/>
</package>
129 changes: 129 additions & 0 deletions mongodb_video_player/scripts/video_server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
#!/usr/bin/env python

import rospy
import cv2
from sensor_msgs.msg import Image
from cv_bridge import CvBridge
from mongodb_media_server import MediaClient
from mongodb_video_player.srv import VideoPlayerService, VideoPlayerServiceRequest, VideoPlayerServiceResponse

from os.path import join, exists, expanduser
from os import makedirs

from threading import Thread


class VideoServer(object):
def __init__(self, name):
rospy.loginfo("Creating "+name+" server")
self.video_folder = join(expanduser('~'), '.ros', 'video_server')
self.video_set = rospy.get_param('~video_set', 'video_set')
self.video_pub = rospy.Publisher(
rospy.get_param("~video_pub", "~video"),
Image,
queue_size=2
)
self.video_index = 0
self.rate = rospy.Rate(25)
self.bridge = CvBridge()
self.thread = None

self.mc = MediaClient(
rospy.get_param("mongodb_host"),
rospy.get_param("mongodb_port")
)

sets = self.mc.get_sets("Video")
object_id = None
for s in sets:
if s[0] == self.video_set:
object_id = s[2]

if object_id is None:
rospy.logwarn('Could not find any set in database matching video_set')
return

file_set = self.mc.get_set(object_id)

if len(file_set) == 0:
rospy.logwarn('No videos available in set ' + self.video_set)

for f in file_set:
print "Media name:", f[0]

if not exists(self.video_folder):
makedirs(self.video_folder)

for f in file_set:
file = self.mc.get_media(str(f[2]))
outfile = open(join(self.video_folder, f[0]), 'wb')
filestr = file.read()
outfile.write(filestr)
outfile.close()

self.file_names = [join(self.video_folder, f[0]) for f in file_set]

self.service = rospy.Service('video_player_service', VideoPlayerService, self.pressed_button)
rospy.loginfo(" ... started "+name)

def pub_video(self, filename):
try:
video = cv2.VideoCapture(filename)
except:
rospy.logwarn("Video %s not found" % filename)
return
if not video.isOpened():
rospy.logwarn("Capture stream could not be opened")
return

fps = rospy.Rate(video.get(cv2.cv.CV_CAP_PROP_FPS))

ret, frame = video.read()
while self.play and ret and not rospy.is_shutdown():
img = self.bridge.cv2_to_imgmsg(frame, "bgr8")
self.video_pub.publish(img)
fps.sleep()
ret, frame = video.read()

def pressed_button(self, req):
if req.player_action == VideoPlayerServiceRequest.PLAY:
self.play = True
self.thread = Thread(target=self.pub_video, args=(self.file_names[self.video_index],))
self.thread.start()
self.paused = False
elif req.player_action == VideoPlayerServiceRequest.PAUSE:
self.paused = True
self.play = False
if self.thread:
self.thread.join()
elif req.player_action == VideoPlayerServiceRequest.PREVIOUS:
self.play = False
if self.thread:
self.thread.join()
self.video_index = self.video_index - 1
if self.video_index < 0:
self.video_index = len(self.file_names)-1
self.play = True
self.thread = Thread(target=self.pub_video, args=(self.file_names[self.video_index],))
self.thread.start()
self.paused = False
elif req.player_action == VideoPlayerServiceRequest.NEXT:
self.play = False
if self.thread:
self.thread.join()
self.video_index = self.video_index + 1
if self.video_index >= len(self.file_names):
self.video_index = 0
self.play = True
self.thread = Thread(target=self.pub_video, args=(self.file_names[self.video_index],))
self.thread.start()
self.paused = False
else:
rospy.logwarn('Service argument has to be 0-3: PLAY, PAUSE, NEXT, PREVIOUS')

return VideoPlayerServiceResponse(self.file_names[self.video_index])

if __name__ == '__main__':
rospy.init_node('video_server')
server = VideoServer(rospy.get_name())
rospy.spin()
7 changes: 7 additions & 0 deletions mongodb_video_player/srv/VideoPlayerService.srv
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
uint8 PLAY=0
uint8 PAUSE=1
uint8 NEXT=2
uint8 PREVIOUS=3
uint8 player_action
---
string video_name
1 change: 1 addition & 0 deletions strands_ui/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
<run_depend>pygame_managed_player</run_depend>
<run_depend>music_player</run_depend>
<run_depend>mongodb_media_server</run_depend>
<run_depend>mongodb_video_player</run_depend>

<export>
<!--<metapackage/> -->
Expand Down