2

First time poster here, so go easy on me.

I'm working on a fun little project for myself and friends, basically I want to be able to stream and recieve video using ffmpeg, as a sort of screen sharing application. I'm a complete python noob and im just going off of the documentation for each. Heres what I have for sending:

import ffmpeg
stream = ffmpeg.input("video.mp4")
stream = ffmpeg.output(stream, "tcp://127.0.0.1:1234", format="mpegts")
ffmpeg.run(stream)

It's simple but it works, when I run ffplay.exe -i tcp://127.0.0.1:1234?listen -hide_banner in a command prompt and run the code to send the video, it works perfectly, but when I try and use my code to recieve a video, all I get is audio, no video, and after the video has finished the last second of the audio is repeated. Heres the recieving code:

from ffpyplayer.player import MediaPlayer
test = MediaPlayer("tcp://127.0.0.1:1234?listen")
while True:
    test.get_frame()
    if test == "eof":
        break

Thanks for any help and sorry if im just being oblivious to something :P

sharp312
  • 183
  • 1
  • 2
  • 8

1 Answers1

1

You are only extracting frames from video.mp4 in your code.

test = MediaPlayer("tcp://127.0.0.1:1234?listen")
while True:
    test.get_frame()
    if test == "eof":
        break

Now, you need to display them using some third-party library since ffpyplayer doesn't provide any inbuilt feature to display frames in a loop.

Below code uses OpenCV to display extracted frames. Install OpenCV and numpy using below command

pip3 install numpy opencv-python

Change your receiver code to

from ffpyplayer.player import MediaPlayer
import numpy as np
import cv2

player = MediaPlayer("tcp://127.0.0.1:1234?listen")
val = ''
while val != 'eof':
    frame, val = player.get_frame()
    if val != 'eof' and frame is not None:
        img, t = frame
        w = img.get_size()[0] 
        h = img.get_size()[1]
        arr = np.uint8(np.asarray(list(img.to_bytearray()[0])).reshape(h,w,3)) # h - height of frame, w - width of frame, 3 - number of channels in frame
        cv2.imshow('test', arr)
        if cv2.waitKey(25) & 0xFF == ord('q'):
            cv2.destroyAllWindows()
            break

you can also run ffplay command directly using python subprocess

Vencat
  • 1,272
  • 11
  • 36
  • I think ill just use subprocess like you suggested, I have no idea what any of this does :P I wanted to make it so everyone using it could just has a single exe file that they could choose to stream or recieve from, but Ill just call ffplay and ffmpeg from subprocess instead, thanks for the help – sharp312 Jan 09 '20 at 11:43
  • @vencat why are we using `cv2.imshow('test',arr)` not `cv.imshow('player',arr)` – Tumul Kumar Jul 15 '21 at 22:45