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 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_descriptorThe 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 removedInstead 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 sideFor 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}')
RE: problem with readline() - schlundreflex - Nov-06-2019 Thank you very much. Works like a charm :) |