Python Forum
problem with readline() - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: problem with readline() (/thread-22228.html)



problem with readline() - schlundreflex - Nov-04-2019

Hi,
I just start to learn pyhton. I'm using 3.7.2 on windows. I have text files which contain full paths of video files, like:
video.lst:
Quote:c:\videos\video1.mp4
c:\videos\video2.mp4
c:\videos\video3.mp4
...


I want to find out how they are encoded with ffprobe. With the full given path of the video file everything works fine:

import os
import subprocess

filePath = r"c:\videos\video1.mp4"

ffprobeResult = subprocess.run(['ffprobe', '-v', 'error', '-select_streams', 'v:0', '-show_entries', 'stream=codec_name', '-of', 'default=noprint_wrappers=1:nokey=1', filePath], universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

print(ffprobeResult.stdout)
What doesn't work:
import os
import subprocess

with open(r"c:\video\video.lst","r") as f:
    filePath = 'r"' + str(f.readline()) + '"'
    
ffprobeResult = subprocess.run(['ffprobe', '-v', 'error', '-select_streams', 'v:0', '-show_entries', 'stream=codec_name', '-of', 'default=noprint_wrappers=1:nokey=1', filePath], universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

print(ffprobeResult.stdout)
It returns:
r"c:\videos\video1.mp4
"
:Invalid argument.

When I change it to
filePath = 'r"' + str(f.readline(18)) + '"'
it works again (18: the bytes of the path). readline seems to add a new line. Does anyone know how to change this or has something else up one's sleeve?

Cheers


RE: problem with readline() - Gribouillis - Nov-04-2019

Try
filepath = f.readline().strip()



RE: problem with readline() - ichabod801 - Nov-04-2019

readline reads the end of line character. You can remove it with f.readline().strip(). That should be all you need. You shouldn't need the 'r"' and the str.


RE: problem with readline() - DeaD_EyE - Nov-04-2019

It's not broken, readline does not remove newline.

In [21]: import io                                                                                                          

In [22]: io.TextIOWrapper.readline?                                                                                         
Signature: io.TextIOWrapper.readline(self, size=-1, /)
Docstring:
Read until newline or EOF.

Returns an empty string if EOF is hit immediately.
Type:      method_descriptor
The returned object from open() is a io.TextIOWrapper and io.BufferedReader in binary mode. All this objects inherits from io.IOBase, which is also a iterator (__next__ method is present). This method iterates one line by calling it.

This means, you can use the returned object from open direct in a for loop:

with open('some_file') as fd:
    for line in fd:
        print(line) # \n is still there!!!
To get rid of the white space (newline is also by definition a white space), use the method strip().


with open('some_file') as fd:
    for line in fd:
        print(line.strip())
        # white spaces on the left
        # and right side are removed
Instead of using subprocess.run, you can use subprocess.check_output.

from subprocess import check_output


with open('some_file') as fd:
    for line in fd:
        file = line.strip()
        result = check_output(['echo', file], encoding='utf8')
        # echo > file
        print(result)
To be more flexible, write small functions. Each function should solve one task.

from pathlib import Path


def read_video_list(file):
    with open(file) as fd:
        for line in fd:
            path = Path(line.strip())
            if path.exists() and path.is_file():
                # path exists and is a file
                # THIS DOES NOT GUARANTEE THAT YOU HAVE READ PERMISSION
                video_codec = video_info(str(path))
                # path is a Path object and must be converted to a
                # str, if you want to add this to the command
                print(path, '->', video_codec) # you can make an own function to print this out


def video_info(video_file):
    cmd = [
        'ffprobe', '-v', 'error', '-select_streams',
        'v:0', '-show_entries', 'stream=codec_name',
        '-of', 'default=noprint_wrappers=1:nokey=1',
        video_file,
    ]
    return check_output(cmd, encoding='utf8').rstrip()
    # rstrip, to remove the newline on the right side
For example, I did not made a function to print the data.
This should be in another function, so that you can exchange it independently.
In this case, the video_info should return both, codec_info and path.

Take also a closer look to pathlib.
In this example Path is just used as a shortcut. Otherwise I had to use os.path.exists and os.path.isfile.


RE: problem with readline() - schlundreflex - Nov-04-2019

Thank you very much for your quick replies/explanations. I'll try them out tomorrow.


RE: problem with readline() - snippsat - Nov-04-2019

Also you do not need stdout=subprocess.PIPE, stderr=subprocess.STDOUT in run().
Can use capture_output=True or can also use check_output() as @DeaD_EyE do.

Here is a test,code is formatted with black so i don't need to do that work,can aslo just use it online Black Playground
import os
import subprocess

with open('video_lst.txt') as f:
    for video_path in f:
        video_path = video_path.strip()
        ffprobeResult = subprocess.run(
            [
                "ffprobe",
                "-v",
                "error",
                "-select_streams",
                "v:0",
                "-show_entries",
                "stream=codec_name",
                "-of",
                "default=noprint_wrappers=1:nokey=1",
                video_path,
            ],
            capture_output=True, text=True
        )
        result = ffprobeResult.stdout.strip()
        print('-' * 15)
        print(f'Video {ffprobeResult.args[-1]} has encoding: {result}') 
Output:
Video G:\1_youtube\planet.mkv has encoding: h264 --------------- Video G:\1_youtube\sky_walk.mkv has encoding: h264



RE: problem with readline() - schlundreflex - Nov-06-2019

Thank you very much. Works like a charm :)