python module ffpyplayer showing or displaying video frames to screen - python

Using python module ffpyplayer, How can I see the frames or get the img object to display or show the video image/frames to the screen?, in the tutorial that I followed, it seems very simple, it reads the frames and plays oudio but (does not display) any video image or frame to the screen, only if I add the (print img, t) will print the frame info to the screen but not video image is displayed on the screen.
I being following tutorials from: https://pypi.python.org/pypi/ffpyplayer, and here: http://matham.github.io/ffpyplayer/player.html, and searched google but the only relevant results point to the same info, I am somewhat new to programming and python, and so maybe I am missing something that seems to be very simple but I can't figure it out myself.
I am using: windows 7 64bit, python 2.7.11 32bit.
Any Help will be appreciated thank you very much.
from ffpyplayer.player import MediaPlayer
vid = 'test_video.flv'
player = MediaPlayer(vid)
val = ''
while val != 'eof':
frame, val = player.get_frame()
if val != 'eof' and frame is not None:
img, t = frame
print img, t #This prints the image object
# display img #This does nothing!

Kivy already provides such a video player, based on ffpyplayer, for you.
It also has the necessary threads already setup for you, to deal with buttons, file reading, audio and timing.
Check this page:
https://kivy.org/docs/api-kivy.uix.videoplayer.html
To install kivy:
https://kivy.org/docs/installation/installation.html
Then you might wish to take a look at the code in:
<< python_path >>\lib\site-packages\kivy\uix\videoplayer.py
That example could be rather complex, so you can also look at this url:
How to play videos from the web like youtube in kivy
Finally, in case Kivy complains that you only have opengl 1.1 (as happened to me), you might try adding the following lines to your code:
from kivy.config import Config
Config.set('graphics', 'multisamples', '0')
These solved the problem to me.

Related

Convert PNG to ZPL and print

I'm trying to convert an image to ZPl and then print the label to a 6.5*4cm label on a TLP 2844 zebra printer on Python.
My main problems are:
1.Converting the image
2.Printing from python to the zebra queue (I've honestly tried all the obvious printing packages like zebra0.5/ win32 print/ ZPL...)
Any help would be appreciated.
I had the same issue some weeks ago. I made a python script specifically for this printer, with some fields available. I commented (#) what does not involve your need, but left it in as you may find it helpful.
I also recommend that you set your printer to the EPL2 driver, and 5cm/s print speed. With this script you'll get the PNG previews with an EAN13 formatted barcode. (If you need other formats, you might need to hit the ZPL module docs.)
Please bear in mind that if you print with ZLP 2844, you will either need to use their paid software, or you will need to manually configure the whole printer.
import os
import zpl
#import pandas
#df= pandas.read_excel("Datos.xlsx")
#a=pandas.Series(df.GTIN.values,index=df.FINAL).to_dict()
for elem in a:
l = zpl.Label(15,25.5)
height = 0
l.origin(3,1)
l.write_text("CUIT: 30-11111111-7", char_height=2, char_width=2, line_width=40)
l.endorigin()
l.origin(2,5)
l.write_text("Art:", char_height=2, char_width=2, line_width=40)
l.endorigin()
l.origin(5.5,4)
l.write_text(elem, char_height=3, char_width=2.5, line_width=40)
l.endorigin()
l.origin(2, 7)
l.write_barcode(height=40, barcode_type='2', check_digit='N')
l.write_text(a[elem])
l.endorigin()
height += 8
l.origin(8.5, 13)
l.write_text('WILL S.A.', char_height=2, char_width=2, line_width=40)
l.endorigin()
print(l.dumpZPL())
lista.append(l.dumpZPL())
l.preview()
To print the previews without having to watch and confirm each preview, I ended up modifying the ZPL preview method, to return an IO variable so I can save it to a file.
fake_file = io.BytesIO(l.preview())
img = Image.open(fake_file)
img = img.save('tags/'+'name'+'.png')
On the Label.py from ZPL module (preview method):
#Image.open(io.BytesIO(res)).show(). <---- comment out the show, but add the return of the BytesIO
return res
I had similar issues and created a .net core application which takes an image and converts it to ZPL, either to a file or to the console so it's pipeable in bash scripts. You could package it with your python app call it as a subprocess like so:
output = subprocess.Popen(["zplify", "path/to/file.png"], stdout=subprocess.PIPE).communicate()[0]
Or feel free to use my code as a reference point and implement it in python.
Once you have a zpl file or stream you can send it directly to a printer using lpr if you're on linux. If on windows you can connect to a printer using it's IP address as shown in this stack overflow question
For what is worth and for anyone else reference, was facing a similar situation and came up with a solution. To whom it may help:
Converting the image?
After trying many libraries i came across ZPLGRF although it seems the demo is focused on PDF only, i found in the source that there is a from_image() class property that could convert from image to zpl combining it part of the demo/exaples. Full code description below
Printing from python to the zebra queue?
Many libraries again but i settled with ZEBRA seem to be the most straight forward one to send raw zpl to a zebra printer
CODE
from zplgrf import GRF
from zebra import Zebra
#Open the image file and generate ZPL from it
with open(path_to_your_image, 'rb') as img:
grf = GRF.from_image(img.read(), 'LABEL')
grf.optimise_barcodes()
zpl_code = grf.to_zpl
#Setup and print to Zebra Printer
z = Zebra()
#This will return a list of all the printers on a given machine as a list
#['printer1', 'printer2', ...]
z.getqueues()
#If or once u know the printer queue name then u can set it up with
z.setqueue('printer1')
#And now is ready to send the raw ZPL text
z.output(zpl_code )
The above i have tested successfully with a Zebra GX430t printer connected via USB in a Windows 11 machine.
Hope it helps

Moviepy unable to read duration of file

I have been using Moviepy to combine several shorter video files into hour long files. Some small files are "broken", they contain video but was not completed correctly (i.e. they play with VLC but there is no duration and you cannot skip around in the video).
I noticed this issue when I try to create a clip using VideoFileClip(file) function. The error that comes up is:
MoviePy error: failed to read the duration of file
Is there a way to still read the "good" frames from this video file and then add them to the longer video?
UPDATE
To clarify, my issue specifically is with the following function call:
clip = mp.VideoFileClip("/home/test/"+file)
Stepping through the code it seems to be an issue when checking the duration of the file in ffmpeg_reader.py where it looks for the duration parameter in the video file. However, since the file never finished recording properly this information is missing. I'm not very familiar with the way video files are structured so I am unsure of how to proceed from here.
You're correct. This issue arises commonly when the video duration info is missing from the file.
Here's a thread on the issue: GitHub moviepy issue 116
One user proposed the solution of using MP4Box to convert the video using this guide: RASPIVID tutorial
The final solution that worked for me involved specifying the path to ImageMagick's binary file as WDBell mentioned in this post.
I had the path correctly set in my environment variables, but it wasn't till I specificaly defined it in config_defaults.py that it started working:
I solved it in a simpler way, with the help of VLC I converted the file to the forma MPEG4 xxx TV/device,
and you can now use your new file with python without any problem
xxx = 720p or
xxx = 1080p
everything depends on your choice on the output format
I already answered this question on the blog: https://github.com/Zulko/moviepy/issues/116
This issue appears when VideoFileClip(file) function from moviepy it looks for the duration parameter in the video file and it's missing. To avoid this (in those corrupted files cases) you should make sure that the total frames parameter is not null before to shoot the function: clip = mp.VideoFileClip("/home/test/"+file)
So, I handled it in a simpler way using cv2.
The idea:
find out the total frames
if frames is null, then call the writer of cv2 and generate a temporary copy of the video clip.
mix the audio from the original video with the copy.
replace the original video and delete copy.
then call the function clip = mp.VideoFileClip("/home/test/"+file)
Clarification: Since OpenCV VideoWriter does not encode audio, the new copy will not contain audio, so it would be necessary to extract the audio from the original video and then mix it with the copy, before replacing it with the original video.
You must import cv2
import cv2
And then add something like this in your code before the evaluation:
cap = cv2.VideoCapture("/home/test/"+file)
frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
fps = int(cap.get(cv2.CAP_PROP_FPS))
print(f'Checking Video {count} Frames {frames} fps: {fps}')
This will surely return 0 frames but should return at least framerate (fps).
Now we can set the evaluation to avoid the error and handle it making a temp video:
if frames == 0:
print(f'No frames data in video {file}, trying to convert this video..')
writer = cv2.VideoWriter("/home/test/fixVideo.avi", cv2.VideoWriter_fourcc(*'DIVX'), int(cap.get(cv2.CAP_PROP_FPS)),(int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)),int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))))
while True:
ret, frame = cap.read()
if ret is True:
writer.write(frame)
else:
cap.release()
print("Stopping video writer")
writer.release()
writer = None
break
Mix the audio from the original video with the copy. I have created a function for this:
def mix_audio_to_video(pathVideoInput, pathVideoNonAudio, pathVideoOutput):
videoclip = VideoFileClip(pathVideoInput)
audioclip = videoclip.audio
new_audioclip = CompositeAudioClip([audioclip])
videoclipNew = VideoFileClip(pathVideoNonAudio)
videoclipNew.audio = new_audioclip
videoclipNew.write_videofile(pathVideoOutput)
mix_audio_to_video("/home/test/"+file, "/home/test/fixVideo.avi", "/home/test/fixVideo.mp4")
replace the original video and delete copys:
os.replace("/home/test/fixVideo.mp4", "/home/test/"+file)
I had the same problem and I have found the solution.
I don't know why but if we enter the path in this method path = r'<path>' instead of ("F:\\path") we get no error.
Just click on the
C:\Users\gladi\AppData\Local\Programs\Python\Python311\Lib\site-packages\moviepy\video\io\ffmpeg_reader.py
and delete the the code and add this one
Provided by me in GITHUB - https://github.com/dudegladiator/Edited-ffmpeg-for-moviepy
clip1=VideoFileClip('path')
c=clip1.duration
print(c)

Can python-pptx module insert video?

according to the documentation, python-pptx can insert videos, however, the documentation does not give very good examples. Anybody have any code snippets to add video1.avi to my pptx?
from pptx import Presentation
pptx1 = Presentation()
slide = pptx1.slides.add_slide(blank_slide_layout)
not sure what inputs I need
slide.placeholders.element.add_placeholder(id_,name,ph_type, orient, sz,idx)
thanks
UPDATE: python-pptx now supports inserting videos (and probably audio in many cases using the same method).
I'm not sure where in the documentation it says it can insert videos, but if you can cite a particular location I'll fix it.
We've looked at this feature, but it turns out to be quite complex as different video formats require a substantial amount of undocumented customization to the metadata inserted into the XML surrounding the embedded video object. Also as I recall one needs a way to get a still image (first frame maybe) from the video to insert in it's place while it's not running, and libraries for this sort of thing are not readily available in Python last time we looked.
Anyway, the short answer is no, it's not supported yet. And it's not likely to come soon unless there's a motivated contributor or sponsor. Sorry I didn't have happier news for you :(
I ended up converting my avi video to an animated gif, and that successfully inserted into the pptx
aviname = 'vid1.avi'
from moviepy.editor import VideoFileClip
aviname = 'vid1.avi'
clip = VideoFileClip(aviname)
clip.write_gif(os.path.splitext(aviname)[0]+'.gif')
The library now has a function for adding videos to slides:
slide.shapes.add_movie(video_file, x_pos, y_pos, width, height, poster_frame_image=thumbnail_image_file)
this video could help you:
https://www.youtube.com/watch?v=5a1kH996DJM&t=315s
he speaks arabic. Here is the code:
import pptx
from pptx.utils import Cm
from pptx.enum.shapes import PP_MEDIA_TYPE
pres = pptx.Presentation()
blank_slide = pres.slides.add_slide(pres.slide_layouts[6])
movie_path = "path"
movie_shape = blank_slide.shapes.add_movie(left = Cm(5), top = Cm(5), width = Cm(10), height = Cm(10), poster_frame_image = "image_path", mime_type = "video/mp4")
movie_shape.media_type = PP_MEDIA_TYPE.MOVIE
pres.save("pres.pptx")

Why are histograms the same [python + simplecv]

My question is why are the two histograms in following code the same.
Because the picture does change, first show shows original picture and second shows completely black picture.
Am I miss-using simpleCV or is this perhaps a bug?
Code:
from itertools import product
from SimpleCV import Image
from SimpleCV import Color
if __name__ == '__main__':
pass
def number_of_hues(picture):
image = Image(picture)
#convert the picture's space to HSV
image = image.toHSV()
image.show()
original_histogram = image.histogram()
(image_x_length, image_y_length) = image.size()
for i,j in product(range(image_x_length), range(image_y_length)):
image[i,j] = Color.BLACK
image.show()
new_histogram = image.histogram()
for o,n in zip(original_histogram, new_histogram):
if o != n:
print o,n
When was the last time you did a pull from the develop github repo? There was a bug in the set item call for the image class that kept images from getting set directly. It was fixed a couple weeks ago. Generally you should try to avoid directly looping over image objects and setting pixels directly as it can be really slow. If you think you found a bug please submit an issue to our github repo and we will try to address it as soon as we can.

Problems using webcam in python + openCV

I am using the following code to access my webcam using openCV + python...
import cv
cv.NamedWindow('webcam_feed', cv.CV_WINDOW_AUTOSIZE)
cam = cv.CaptureFromCAM(-1)
I am then getting the following error in the console...
VIDIOC_QUERYMENU: Invalid argument
VIDIOC_QUERYMENU: Invalid argument
VIDIOC_QUERYMENU: Invalid argument
I was originally using,
cv.CaptureFromCAM(0)
to access the same and had the same issue and used -1 because it is suppose to pick up any webcam.
I also tested to see if Ubuntu recognizes the webcam and it does. I am using v4l2 for the webcam.
{EDIT}
I am using the following code to display a video feed, it seems to only be showing just one image the web cam captured instead of a continuous video feed...
import cv
cv.NamedWindow('webcam_feed', cv.CV_WINDOW_AUTOSIZE)
cam = cv.CaptureFromCAM(-1)
feed = cv.QueryFrame(cam)
cv.ShowImage("webcam_feed", feed)
cv.WaitKey(-1)
WOW, answered my own question in 15 after me posting this. I did some research and the reason for the web cam only grabbing one image is because of the...
cv.WaitKey(-1)
This doesn't allow the contents of the window to refresh. I set the number to 10...
cv.WaitKey(10)
and it worked beautifully. I also tried 100, but saw no difference. I only saw a difference when the number was 1000. I use 1 because seems that it runs the smoothest.
Here is the full code to display a web cam feed
import cv
cv.NamedWindow("webcam", 1)
cam = cv.CaptureFromCAM(-1)
While True:
feed = cv.QueryFrame(cam)
cv.ShowImage("webcam", feed)
cv.WaitKey(1)
I believe you need to put
frame = cv.QueryFrame(cam)
cv.ShowImage("Webcam Feed", frame)
in a loop to continuously update the image shown in the window. That is, the frame from cv.QueryFrame is a static image, not a continuous video.
If you want to be able to exit with a key press, test cv.WaitKey with a small timeout in the loop too.
For me, the command in root
xhost +
save my time, Note to close and open new terminal.
See you.

Categories