def get_video_duration(path): probe = ffmpeg.probe(path) video_stream = next( (stream for stream in probe['streams'] if stream['codec_type'] == 'video'), None) time_base = video_stream["time_base"] duration_ts = video_stream["duration_ts"] duration = convert_fraction(time_base) * float(duration_ts) return duration
def get_num_frames(video_path): """Returns the number of frames in the given video (approximated via FFprobe). :param video_path: Path to the video file (str) :return: int """ ffprobe_result = ffmpeg.probe(video_path, select_streams='v:0') num_frames = int(ffprobe_result['streams'][0]['nb_frames']) return num_frames
def has_audio_stream(video_url: typing.Optional[str]) -> bool: if not video_url: return False info = ffmpeg.probe(video_url, select_streams='a', show_entries='format=:streams=index') streams = info.get('streams', []) return len(streams) > 0
def concat_demuxer(in_files, output_path, *args): """ Concatenate media files with exactly the same codec and codec parameters. Different container formats can be used and it can be used with any container formats. """ for input_path in in_files: try: info = ffmpeg.probe(input_path) except ffmpeg._run.Error as e: log_ffmpeg_error(e, "concat_demuxer") raise (e) streams = info["streams"] if len(streams) != 2: return { "success": False, "message": "%s has an unexpected stream number (%s)" % (input_path, len(streams)), } stream_infos = {streams[0]["codec_type"], streams[1]["codec_type"]} if stream_infos != {"video", "audio"}: return { "success": False, "message": "%s has unexpected stream type (%s)" % ( input_path, {streams[0]["codec_type"], streams[1]["codec_type"]}, ), } video_index = [ x["index"] for x in streams if x["codec_type"] == "video" ][0] if video_index != 0: return { "success": False, "message": "%s has an unexpected stream order" % input_path, } with tempfile.NamedTemporaryFile(mode="w") as temp: for input_path in in_files: temp.write("file '%s'\n" % input_path) temp.flush() stream = ffmpeg.input(temp.name, format="concat", safe=0) stream = ffmpeg.output(stream.video, stream.audio, output_path, c="copy") return run_ffmpeg(stream, "-xerror")
def deal_video(video_dir, save_dir, start_time=15, end_time=12): for video in os.listdir(video_dir): video_path = os.path.join(video_dir, video) video_time = float(ffmpeg.probe(video_path)['format']['duration']) during_time = video_time - start_time - end_time # video_detail_time = get_time(video_time) cut_start_time = str(get_time(start_time)).split(" ")[1] during_time = str(get_time(during_time)).split(" ")[1] video_out_path = os.path.join(save_dir, video) cut_video(video_path, video_out_path, cut_start_time, during_time)
def select_p_frame_b4_i_frame(self, output_dir="pframe", n=1, frames=None): """ output the p_frame before i_frame of a video :param output_dir=None, :param n: select the last n frame before i-frame :param frames: ffmpeg.probe( self.video_path, select_streams="v", show_entries="frame=pkt_pts_time,pict_type")["frames"] :return: stdout, stderr """ ## ffprobe -i example.mp4 -v quiet -select_streams v -show_entries frame=pkt_pts_time,pict_type ## ffmpeg -ss 1.835167 -i example.mp4 -vframes 1 0.jpg os.makedirs(output_dir, exist_ok=True) if not frames: frames = ffmpeg.probe( self.video_path, select_streams="v", show_entries="frame=pkt_pts_time,pict_type")["frames"] count = 1 sequence_thumb = [{"path": f"{output_dir}/core-{count}.jpg", "pts": 0}] frame_num_list = [{"frame": 0, "count": count}] for num, frame in enumerate(frames): pict_type = frame['pict_type'] if num > 1 and pict_type == "I": count += 1 frame_num_list.append({"frame": num - n, "count": count}) last_n_frame = frames[num - n] pkt_pts_time = last_n_frame['pkt_pts_time'] sequence_thumb.append({"path": f"{output_dir}/core-{count}.jpg", "pts": pkt_pts_time}) else: count += 1 frame_num_list.append({"frame": len(frames) - 1, "count": count}) sequence_thumb.append({"path": f"{output_dir}/core-{count}.jpg", "pts": frames[-1]["pkt_pts_time"]}) statement = "+".join( list( map( lambda x: f"eq(n\,0)", frame_num_list ) ) ) stdout, stderr = ( ffmpeg .input(self.video_path) .output( f"{output_dir}/core-%d.jpg", vf=f"select='{statement}'", vsync=0, loglevel="fatal", ) .run_async(pipe_stdout=True, pipe_stderr=True, overwrite_output=True) ).communicate() return sequence_thumb, stdout, stderr
def testStichOneImage(self): filename = "20210903T120000000-Screenshot.jpg" timezone = "US/Eastern" image_path_1 = self._createImage(800, 600, 0, filename) video_start_epoch_s = file_naming.parse_epoch_seconds_from_filename(filename, timezone) start_time_epoch_s = video_start_epoch_s - 5.0 out_mp4_path = os.path.join(self.get_temp_dir(), "stiched.mp4") video.stitch_images_into_mp4([image_path_1], start_time_epoch_s, timezone, out_mp4_path) probe = ffmpeg.probe(out_mp4_path) self.assertAllClose(float(probe["streams"][0]["duration"]), 5.0, atol=0.1)
def get_trailers(session, max=99): series = get_session_series(session) trailers = list( filter(lambda x: x not in series, [{ 'input': ffmpeg.input(trailer), 'data': ffmpeg.probe(trailer) } for trailer in glob.glob('Trailers/*.mp4')])) shuffle(trailers) if len(trailers) > max: return trailers[:max] return trailers
def get_resolution(video_path): """Returns the resolution (H, W) of the given video (approximated via FFprobe). :param video_path: Path to the video file (str) :return: 2-tuple of int """ ffprobe_result = ffmpeg.probe(video_path, select_streams='v:0') width = ffprobe_result['streams'][0]['width'] height = ffprobe_result['streams'][0]['height'] return width, height
def split(self, split_interval: int = 3600) -> None: if split_interval <= 0: split_interval = 3600 duration = float( ffmpeg.probe(self.merged_file_path)['format']['duration']) num_splits = int(duration) // split_interval + 1 for i in range(num_splits): output_file = os.path.join( self.splits_dir, f"{self.room_id}_{self.global_start}_{i}.mp4") cmd = f'ffmpeg -y -ss {i*split_interval} -t {split_interval} -accurate_seek -i "{self.merged_file_path}" -c copy -avoid_negative_ts 1 "{output_file}"' _ = subprocess.run(cmd, shell=True, check=True)
def get_video_info(in_file): try: probe = ffmpeg.probe(in_file) video_stream = next((stream for stream in probe['streams'] if stream['codec_type'] == 'video'), None) if video_stream is None: print('No video stream found', file=sys.stderr) sys.exit(1) return video_stream except ffmpeg.Error as err: print(str(err.stderr, encoding='utf8')) sys.exit(1)
def get_duration(file_path): try: probe = ffmpeg.probe(file_path) audio_stream = next( (stream for stream in probe["streams"] if stream["codec_type"] == "audio"), None, ) except ffmpeg._run.Error as e: return Decimal(0) return Decimal(audio_stream["duration"])
def get_video_aspect(video_filename): """Returns width, height of video using ffmpeg-python""" if not os.path.exists(video_filename): raise ValueError("%s does not exist" % video_filename) probe = ffmpeg.probe(video_filename) assert len(probe['streams']) == 1 width = probe['streams'][0]['width'] height = probe['streams'][0]['height'] return width, height
def get_video_info(self, file_path: str): probe = ffmpeg.probe(file_path) video_stream = next( (stream for stream in probe["streams"] if stream["codec_type"] == "video"), None, ) width = int(video_stream["width"]) height = int(video_stream["height"]) duration = float(video_stream["duration"]) return {"width": width, "height": height, "duration": duration}
def get_video_data(video_file, location_video_file=None): logger.debug(f'Reading video data for video {video_file}') ffprobe_res = ffmpeg.probe(video_file, cmd='ffprobe') video_duration = float(ffprobe_res['format']['duration']) video_nb_frames = int(ffprobe_res['streams'][0]['nb_frames']) video_size = (int(ffprobe_res['streams'][0]['width']), int(ffprobe_res['streams'][0]['height'])) try: location_string = ffprobe_res['format']['tags']['location'] except KeyError: if location_video_file: ffprobe_res = ffmpeg.probe(location_video_file, cmd='ffprobe') location_string = ffprobe_res['format']['tags']['location'] else: location_string = None video_pos = (None, None) if location_string: match = re.match(r'([-+]\d+.\d+)([-+]\d+.\d+)([-+]\d+.\d+)', location_string) if match: video_pos = (float(match.group(1)), float(match.group(2))) return video_duration, video_nb_frames, video_size, video_pos
def test_save(adapter, audio_data): """ Test audio saving. """ with TemporaryDirectory() as directory: path = join(directory, 'ffmpeg-save.mp3') adapter.save(path, audio_data[0], audio_data[1]) probe = ffmpeg.probe(TEST_AUDIO_DESCRIPTOR) assert len(probe['streams']) == 1 stream = probe['streams'][0] assert stream['codec_type'] == 'audio' assert stream['channels'] == 2 assert stream['duration'] == '10.919184'
def get_info(filepath): try: import ffmpeg except ImportError: logger.error( 'Import Error! Cant import ffmpeg. ' 'Annotations operations will be limited. import manually and fix errors' ) raise probe = ffmpeg.probe(filepath) return probe
def check_rotation(path_video_file): val = 0 # this returns meta-data of the video file in form of a dictionary meta_dict = ffmpeg.probe(path_video_file) # from the dictionary, meta_dict['streams'][0]['tags']['rotate'] is the key # we are looking for rotate_code = None rotate = meta_dict.get('streams', [dict(tags=dict())])[0].get( 'tags', dict()).get('rotate', 0) val = round(int(rotate) / 90.0) * 90 return val
def get_video_info(input_file_path): probe = ffmpeg.probe(input_file_path) video_stream = next( (stream for stream in probe['streams'] if stream['codec_type'] == 'video'), None) width = int(video_stream['width']) height = int(video_stream['height']) duration = float(video_stream['duration']) # print(width, height, duration) return video_stream
def extract_duration_from_non_YT_video(source_mp4, headers): file_name = 'trial_video.mp4' #print(source_mp4) rsp = urlopen(Request(source_mp4, None, headers)) with open(file_name, 'wb') as f: f.write(rsp.read()) probe = ffmpeg.probe(file_name) duration = probe['streams'][1]['duration'] os.remove(file_name) #print(probe) return (duration)
def get_video_props(filename): logger.info('Getting video properties from %s' % filename) probe = ffmpeg.probe(filename) video_info = next(s for s in probe['streams'] if s['codec_type'] == 'video') width = int(video_info['width']) height = int(video_info['height']) s = video_info['r_frame_rate'].split("/") fps = float(s[0]) / float(s[1]) duration = float(probe['format']['duration']) return width, height, fps, duration
def scrape_file(self): """Scrape A/V files.""" if not self._check_wellformed and self._only_wellformed: self._messages.append("Skipping scraper: Well-formed check not " "used.") return try: probe_results = ffmpeg.probe(encode_path(self.filename)) streams = [probe_results["format"]] + probe_results["streams"] for stream in streams: if "index" not in stream: stream["index"] = 0 else: stream["index"] = stream["index"] + 1 except ffmpeg.Error as err: self._errors.append("Error in analyzing file.") self._errors.append(ensure_text(err.stderr)) shell = Shell([ "ffmpeg", "-v", "error", "-i", encode_path(self.filename), "-f", "null", "-" ]) if shell.returncode == 0: self._messages.append("The file was analyzed successfully.") # if "truncated" in self.filename: # __import__('pdb').set_trace() if self._filter_stderr(shell.stderr): self._errors.append(shell.stderr) return container = False for index in range(len(streams)): # FFMpeg has separate "format" (relevant for containers) and # "streams" (relevant for all files) elements in its output. We # know whether we'll have streams + container or just streams only # after scraping the first stream, so there's a risk of trying to # add one too many streams. This check prevents constructing more # metadata models than there are streams. if not container and index == len(streams) - 1: break for md_class in self._supported_metadata: if md_class.is_supported(self._mimetype_guess): stream = md_class(probe_results, index, self._given_mimetype, self._given_version) self.streams.append(stream) if stream.hascontainer(): container = True self._check_supported(allow_unav_mime=True, allow_unav_version=True)
def __init__(self, video_path, temp_dir=None, time_range: (Decimal, Decimal) = None): probe = ffmpeg.probe(video_path, skip_frame="nokey", show_entries="frame=pkt_pts_time", select_streams="v:0") self.vcodec = ffmpeg.probe(video_path, select_streams="v:0")['streams'][0]['codec_name'] self.acodec = ffmpeg.probe(video_path, select_streams="a:0")['streams'][0]['codec_name'] self.key_frame_timestamps = [Decimal(frame['pkt_pts_time']) for frame in probe['frames']] self.duration = Decimal(probe['streams'][0]['duration']) self.video_path = video_path if time_range is None: self.input_file: ffmpeg.nodes.FilterableStream = ffmpeg.input(video_path) self.time_range = (Decimal(0), self.duration) else: start_key_frame = self.find_before_timestamp(time_range[0]) end_key_frame = self.find_after_timestamp(time_range[1]) self.input_file: ffmpeg.nodes.FilterableStream = \ ffmpeg.input(video_path, ss=start_key_frame, to=end_key_frame, copyts=None) self.time_range = time_range if temp_dir is not None: self.temp_dir = mkdtemp(dir=temp_dir) else: self.temp_dir = mkdtemp()
def show_data(self): print("ok") fname = qtw.QFileDialog.getOpenFileName(self, 'Open file', 'c:\\',"Video Files (*.mp4 *.flv *.ts *.mts *.avi *.mkv)") videoname_url = str(fname[0]) self.ui.label_videoname.setText(videoname_url) data_list =[] media_info = MediaInfo.parse(videoname_url) for track in media_info.tracks: if track.track_type == "Video": print("Bit rate: {t.bit_rate}, Frame rate: {t.frame_rate}, " "Format: {t.format}".format(t=track) ) print("Duration (raw value):", track.duration) #print("Duration (other values:") pprint(track.other_duration) self.ui.textEdit_data.append( "Bit rate: {t.bit_rate}, Frame rate: {t.frame_rate}, Format: {t.format}".format(t=track)) self.ui.textEdit_data.append("Duration (raw value):" + str(track.duration) + '\n') self.ui.textEdit_data.append(str(track.other_duration)) #self.ui.textEdit_data.setText(self.ui.textEdit_data.text() + str(track )) elif track.track_type == "Audio": print("Track audio-data:") pprint(track.to_data()) data_dict = track.to_data() for key, val in data_dict.items(): print(key) self.ui.textEdit_data.append("Track audio-data:" + str(key) + " : " + str(val)) in_file = ffmpeg.input(videoname_url) probe = ffmpeg.probe(videoname_url) video_stream = next((stream for stream in probe['streams'] if stream['codec_type'] == 'video'), None) video_stream2 = next((stream for stream in probe['streams']), None) # width = int(video_stream['width']) # height = int(video_stream['height']) print(type(video_stream2)) for key, value in video_stream2.items(): print(key, " : ", value ) file_data = str(key) + " : " + str(value) self.ui.textEdit_data.append(str(file_data)) # for stream_item in enumerate(video_stream2): # print(video_stream2[stream_item]) for my_data_x in probe['streams']: pass
def get_movie_size(movie_path): """ Returns movie resolution (extract a frame and returns its size). """ probe = ffmpeg.probe(movie_path) video = next( (stream for stream in probe['streams'] if stream['codec_type'] == 'video'), None) width = int(video['width']) height = int(video['height']) return (width, height)
def __init__(self, input_path): self._filelists = [] self._i = 0 for dir_path, subdir_list, file_list in os.walk(input_path): for fname in file_list: full_path = os.path.join(dir_path, fname) try: info = AudioFileInfo(ffmpeg.probe(full_path)) if self._is_right_file(info): self._filelists.append(info) except ffmpeg._run.Error: pass
def get_content_with_xml_info(content_path: Path, content_type: ContentType) -> AudioVideoContent: filename = content_path.stem xml_info_file = content_path.parent / f"{filename}.xml" start_date = get_content_start_date_from_xml(xml_info_file) duration = timedelta( seconds=float(ffmpeg.probe(content_path)["format"]["duration"])) return AudioVideoContent(path=content_path, content_type=content_type, start_date=start_date, duration=duration)
def _get_video_info(self, uri): try: probe = ffmpeg.probe(uri) # can raise ffmpeg.Error except ffmpeg.Error as e: raise ValueError( 'URI cannot be connected or incorrect: {}'.format(uri)) video_info = next( (s for s in probe['streams'] if s['codec_type'] == 'video'), None) if video_info is None: raise ValueError('No video stream found in {}.'.format(uri), file=sys.stderr) return video_info
def get_frame_size(self): with open(RECORD_FILE, 'wb+') as f: data = self.stream_fd.read(4 * 1024) f.write(data) probe = ffmpeg.probe(RECORD_FILE) video_stream = next((stream for stream in probe['streams'] if stream['codec_type'] == 'video'), None) self.width = int(video_stream['width']) self.height = int(video_stream['height']) self.frame_size = self.width * self.height * 3 print(f"ffprobe: w={self.width} h={self.height}") os.remove(RECORD_FILE)
def get_rotation_correct(path): meta_dict = ffmpeg.probe(path) rotation = None if int(meta_dict['streams'][0]['tags']['rotate']) == 90: rotation = cv.ROTATE_90_CLOCKWISE elif int(meta_dict['streams'][0]['tags']['rotate']) == 180: rotation = cv.ROTATE_180 elif int(meta_dict['streams'][0]['tags']['rotate']) == 270: rotation = cv.ROTATE_90_COUNTERCLOCKWISE return rotation