I am streaming images from python to youtube using ffmpeg.
It's working fine with just one problem.
Sometimes the stream get somehow corrupted an the stream looks like this:
Corrupted stream image
Or you can see for yourself in the stream itself: https://www.youtube.com/watch?v=PG6NLtr0jjM (Scroll back to the beginning)
Then I have to restart ffmpeg and its working fine. Sometimes an error occurs regarding the network and I have to automatically restart the stream. Then there is the possibility it is corrupted again.
The parameters for ffmpeg are the following:
cmd_out = ['ffmpeg',
'-re',
'-f', 'concat',
'-i', os.path.join(BASE_DIR, 'music', 'music.txt').replace('\\', '/'),
'-r', '1',
'-f', 'image2pipe',
'-vcodec', 'png',
'-r', '1',
'-i', '-',
'-c:v', 'libx264',
'-c:a', 'copy',
'-g', '4',
'-f', 'flv',
'rtmp://a.rtmp.youtube.com/live2/{}'.format(stream_key)]
I never had that problem testing it on windows. It just appears when I use my linux server.
I am using ffmpeg version 3.2.18-0+deb9u1 and the generated images are fine, when I save them to a normal file.
Does someone know how to fix it? Or where the problem is comming from?
Solution: An old ffmpeg version was available while using docker. I solved the problem by using a static build from https://www.johnvansickle.com/ffmpeg/
I used this to use it in docker:
WORKDIR /app
ADD ./ffmpeg /app
RUN mv ffmpeg /usr/local/ffmpeg
RUN chmod +x /usr/local/ffmpeg
Until now the error seems to be solved.
Related
Using python3.10.6 and docker 20.10.23, build 7155243 on Ubuntu 22.04. And trying not to use the docker module but just subprocess to load a docker image
def run(params):
output = subprocess.run(params, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if output.returncode == 0:
print(output.stdout.decode())
else:
print(output.stderr.decode())
run(['sudo', 'docker', 'load', '<', 'PATH/OF/AIMAGE.zip'])
run(['sudo', 'docker', 'run', '-t', '-d', '-v', PATH_REPO + ':/root/windows-mount', 'IMAGE:v3'])
I can see the image is loaded fine by using sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
96d1f80916ce IMAGE:v3 "/bin/bash" 53 seconds ago Up 52 seconds happy_joliot
but the docker load always output an error:
"docker load" accepts no arguments.
See 'docker load --help'.
Usage: docker load [OPTIONS]
Load an image from a tar archive or STDIN
[docerapp.py:66]
Any suggestion to fix the error?
Instead of using '<' which means Load images from STDIN , '-i' / '--input' meaning Load images from a file should be used in the script.
run(['sudo', 'docker', 'load', '-i', 'PATH/OF/AIMAGE.zip'])
I'm working on a python script to automate sound and video clip processing. So far I've been able to run ffmpeg commands in python using subprocess, e.g:
#extract video audio
subprocess.call(['ffmpeg', '-i', 'video.mp4', 'vid_audio.mp3'])
However, I can't seem to get the following command split into a list that works with subprocess.
#merge two audio tracks with scaled volume
ffmpeg -i audio1.mp3 -i audio2.mp3 -filter_complex "[0:a]volume=.3[A];[1:a] [A]amerge[out]" -map [out] -c:a libmp3lame -q:a 4 audiofinal.mp3
Any help on how to split the above command into a list that works with subprocess would be greatly appreciated!
The command does not save or even create a file:
ffmpeg -i "video.mp4" -f mp3 "audio.mp3" -vstats_file "log_file.log"
And if you convert to a video file, everything normally creates and writes:
ffmpeg -i "video.mp4" -f mp3 "video.avi" -vstats_file "log_file.log"
Goal: to pull out the time from the log file and bind it to the process bar.
There are no problems with video, everything works. But with the sound does not work.
I tried the command:
ffmpeg -i "video.mp4" -f mp3 "video.avi" >2 "log_file.txt"
But there are other problems popping out. Since I run it all from the python using the subprocess
ffmpegProc = subprocess.Popen(ffmpegCommand, startupinfo=startupinfo, shell=True)
, I can not kill the running process, because it is started with the attribute shell=True, and only the shell is killed.and only the shell is killed.
-vstats is for video encoding statistics. When writing an audio file, there's no video encoding. Use the -progress option.
ffmpeg -i "video.mp4" -f mp3 "audio.mp3" -progress "log_file.log"
You'll get blocks such as these:
bitrate= 126.2kbits/s
total_size=7695851
out_time_ms=487944127
out_time=00:08:07.944127
dup_frames=0
drop_frames=0
speed=19.5x
progress=continue
Search for the last out_time and that's your progress status.
I am intresting in launching an xterm window from python code in following way:
cmd = './my_task'
subprocess.Popen(['xterm', '-t', 'my_task', '-e', cmd])
However, I want this xterm session to be set to always on top from command line.
One way I was able to do this is by doing this:
cmd = 'wmcntl -r 'my_task' -b add,above; ./my_task'
subprocess.Popen(['xterm', '-t', 'my_task', '-e', cmd])
But this requires the machine to have wmctrl installed.
Is there a standard way of doing this (I don't need a cross platform solution, just for Linux)
Thanks,
Itay
I'm wondering if someone can either direct me to a example or help me with my code for running commands on linux(centos). Basically, I am assuming I have a basic fresh server and want to configure it. I thought I could list the commands I need to run and it would work but I'm getting errors. The errors are related to nothing to make(when making thift).
I think this is because(I'm just assuming here) that python is just sending the code to run and then sending another and another and not waiting for each command to finish running(after the script fails, I check and the thrift package is downloaded and successfully uncompressed).
Here's the code:
#python command list to setup new server
import commands
commands_to_run = ['yum -y install pypy autocon automake libtool flex boost-devel gcc-c++ byacc svn openssl-devel make java-1.6.0-openjdk git wget', 'service mysqld start',
'wget http://www.quickprepaidcard.com/apache//thrift/0.8.0/thrift-0.8.0.tar.gz', 'tar zxvf thrift-0.8.0.tar.gz',
'cd thrift-0.8.0', './configure', 'make', 'make install' ]
for x in commands_to_run:
print commands.getstatusoutput(x)
Any suggestions on how to get this to work? If my approach is totally wrong then let me know(I know I can use a bash script but I'm trying to improve my python skills).
Since commands has been deprecated for a long time, you should really be using subprocess, specifically subprocess.check_output. Also, cd thrift-0.8.0 only affects the subprocess, and not yours. You can either call os.chdir or pass the cwd argument to subprocess functions:
import subprocess, os
commands_to_run = [['yum', '-y', 'install',
'pypy', 'python', 'MySQL-python', 'mysqld', 'mysql-server',
'autocon', 'automake', 'libtool', 'flex', 'boost-devel',
'gcc-c++', 'perl-ExtUtils-MakeMaker', 'byacc', 'svn',
'openssl-devel', 'make', 'java-1.6.0-openjdk', 'git', 'wget'],
['service', 'mysqld', 'start'],
['wget', 'http://www.quickprepaidcard.com/apache//thrift/0.8.0/thrift-0.8.0.tar.gz'],
['tar', 'zxvf', 'thrift-0.8.0.tar.gz']]
install_commands = [['./configure'], ['make'], ['make', 'install']]
for x in commands_to_run:
print subprocess.check_output(x)
os.chdir('thrift-0.8.0')
for cmd in install_commands:
print subprocess.check_output(cmd)
Since CentOS maintains ancient versions of Python, you may want to use this backport instead.
Note that if you want to print the output out anyways, you can just call the subprocess with check_call, since the subprocess inherits your stdout,stderr, and stdin by default.