Skip to content

Commit

Permalink
moved av.open() with timeout to constructor
Browse files Browse the repository at this point in the history
moved av.open() with timeout to constructor
  • Loading branch information
ehong-tl committed Nov 17, 2021
1 parent c87b434 commit 788526a
Show file tree
Hide file tree
Showing 6 changed files with 23 additions and 38 deletions.
32 changes: 20 additions & 12 deletions djitellopy/tello.py
Expand Up @@ -29,7 +29,7 @@ class Tello:
# Send and receive commands, client socket
RESPONSE_TIMEOUT = 7 # in seconds
TAKEOFF_TIMEOUT = 20 # in seconds
FRAME_GRAB_TIMEOUT = 3
FRAME_GRAB_TIMEOUT = 5
TIME_BTW_COMMANDS = 0.1 # in seconds
TIME_BTW_RC_CONTROL_COMMANDS = 0.001 # in seconds
RETRY_COUNT = 3 # number of retries after a failed command
Expand Down Expand Up @@ -1011,8 +1011,17 @@ class BackgroundFrameRead:

def __init__(self, tello, address):
self.address = address
self.frame = None
self.frame = np.zeros([300, 400, 3], dtype=np.uint8)

# Try grabbing frame with PyAV
# According to issue #90 the decoder might need some time
# https://github.com/damiafuentes/DJITelloPy/issues/90#issuecomment-855458905
try:
Tello.LOGGER.debug('trying to grab video frames...')
self.container = av.open(self.address, timeout=(Tello.FRAME_GRAB_TIMEOUT, None))
except av.error.ExitError:
raise Exception('Failed to grab video frames from video stream')

self.stopped = False
self.worker = Thread(target=self.update_frame, args=(), daemon=True)

Expand All @@ -1026,16 +1035,15 @@ def update_frame(self):
"""Thread worker function to retrieve frames using PyAV
Internal method, you normally wouldn't call this yourself.
"""
Tello.LOGGER.debug('trying to grab video frames...')
self.container = av.open(self.address)

Tello.LOGGER.debug('video frames received, decoding...')
for frame in self.container.decode(video=0):
self.frame = np.array(frame.to_image())
if self.stopped:
self.container.close()
break

try:
for frame in self.container.decode(video=0):
self.frame = np.array(frame.to_image())
if self.stopped:
self.container.close()
break
except av.error.ExitError:
raise Exception('Do not have enough frames for decoding, please try again or increase video fps before get_frame_read()')

def stop(self):
"""Stop the frame update worker
Internal method, you normally wouldn't call this yourself.
Expand Down
8 changes: 1 addition & 7 deletions examples/manual-control-opencv.py
Expand Up @@ -14,12 +14,6 @@
tello.streamon()
frame_read = tello.get_frame_read()

# Wait for video frames before doing other things
while True:
if frame_read.frame is not None:
break
time.sleep(1)

tello.takeoff()

while True:
Expand Down Expand Up @@ -48,4 +42,4 @@
elif key == ord('f'):
tello.move_down(30)

tello.land()
tello.land()
6 changes: 0 additions & 6 deletions examples/manual-control-pygame.py
Expand Up @@ -56,12 +56,6 @@ def run(self):

frame_read = self.tello.get_frame_read()

# Wait for video frames before doing other things
while True:
if frame_read.frame is not None:
break
time.sleep(1)

should_stop = False
while not should_stop:

Expand Down
6 changes: 0 additions & 6 deletions examples/record-video.py
Expand Up @@ -10,12 +10,6 @@
tello.streamon()
frame_read = tello.get_frame_read()

# Wait for video frames before doing other things
while True:
if frame_read.frame is not None:
break
time.sleep(1)

def videoRecorder():
# create a VideoWrite object, recoring to ./video.avi
height, width, _ = frame_read.frame.shape
Expand Down
6 changes: 0 additions & 6 deletions examples/take-picture.py
Expand Up @@ -7,12 +7,6 @@
tello.streamon()
frame_read = tello.get_frame_read()

# Wait for video frames before doing other things
while True:
if frame_read.frame is not None:
break
time.sleep(1)

tello.takeoff()
cv2.imwrite("picture.png", frame_read.frame)

Expand Down
3 changes: 2 additions & 1 deletion requirements.txt
@@ -1,2 +1,3 @@
numpy==1.20.1
av==8.0.3
av==8.0.3
pillow==8.4.0

0 comments on commit 788526a

Please sign in to comment.