def save_image(fname, img, codec='bmp', pix_fmt='', lib_opts={}): """Saves the given image to disk in the format requested. :param fname: The filename where to save the image. :param img: The :class:`ffpyplayer.pic.Image` to save. :param codec: The codec to pass to :class:`ffpyplayer.writer.MediaWriter` that determines the image type. Defaults to 'bmp'. :param pix_fmt: The pixel format into which to convert the image before saving. If empty, the original pixel format is used. If the codec doesn't support the image format, we first convert it to the closest supported format. :param lib_opts: Any additional `lib_opts` options to pass to :class:`ffpyplayer.writer.MediaWriter`. :return: The estimated size of the image on disk. """ fmt = img.get_pixel_format() w, h = img.get_size() if not codec: codec = get_format_codec(fname) ofmt = get_supported_pixfmts(codec, fmt)[0] else: ofmt = get_supported_pixfmts(codec, pix_fmt or fmt)[0] if ofmt != fmt: sws = SWScale(w, h, fmt, ofmt=ofmt) img = sws.scale(img) fmt = ofmt out_opts = {'pix_fmt_in': fmt, 'width_in': w, 'height_in': h, 'frame_rate': (30, 1), 'codec': codec} writer = MediaWriter(fname, [out_opts], lib_opts=lib_opts) size = writer.write_frame(img=img, pts=0, stream=0) writer.close() return size
def test_write_smaller_than_frame_rate(tmp_path, fmt): from ffpyplayer.writer import MediaWriter fname = str(tmp_path / 'test_frame.') + fmt[0] w, h = 64, 64 out_opts = { 'pix_fmt_in': 'rgb24', 'width_in': w, 'height_in': h, 'codec': 'rawvideo', 'pix_fmt_out': 'yuv420p', 'frame_rate': (30, 1) } writer = MediaWriter(fname, [out_opts], fmt=fmt[1]) img = get_image(w, h) if fmt[0] == 'avi': with pytest.raises(Exception): for i in range(20): writer.write_frame(img=img, pts=i / 300, stream=0) else: for i in range(20): writer.write_frame(img=img, pts=i / 300, stream=0) writer.close()
def test_write_larger_than_frame_rate(tmp_path, fmt): from ffpyplayer.writer import MediaWriter fname = str(tmp_path / 'test_frame.') + fmt[0] w, h = 64, 64 out_opts = { 'pix_fmt_in': 'gray', 'width_in': w, 'height_in': h, 'codec': 'rawvideo', 'frame_rate': (15, 1) } writer = MediaWriter(fname, [out_opts], fmt=fmt[1]) timestamps = [] image_vals = [] for i in range(20): timestamps.append(i) image_vals.append(i * 5) writer.write_frame(img=get_gray_image_with_val(w, h, i * 5), pts=i, stream=0) writer.close() verify_frames(fname, timestamps, image_vals)
def video_file(tmp_path_factory): from ffpyplayer.writer import MediaWriter from ffpyplayer.pic import Image fname = str(tmp_path_factory.mktemp('data') / 'test_video.avi') w, h = 64, 64 size = w * h out_opts = { 'pix_fmt_in': 'gray', 'width_in': w, 'height_in': h, 'codec': 'rawvideo', 'frame_rate': (2997, 100) } buf = bytearray([int(x * 255 / size) for x in range(size)]) buf2 = bytearray([0] * size) img = Image(plane_buffers=[buf, buf2], pix_fmt='gray', size=(w, h)) writer = MediaWriter(fname, [out_opts]) for i in range(20): writer.write_frame(img=img, pts=i / 29.97, stream=0) writer.close() return fname
def save_video_thumbnail(source, output): """Saves thumbnail of the given video under the given name""" player = MediaPlayer(source, ff_opts={'ss': 1.0}) frame, val = None, None while not frame: frame, val = player.get_frame(force_refresh=True) player.close_player() if val == 'eof': return None elif frame is None: return None else: img = frame[0] pixel_format = img.get_pixel_format() img_size = img.get_size() thumb_size = 256, int(img_size[1] * 256 / img_size[0]) codec = 'tiff' output_format = get_supported_pixfmts(codec, pixel_format)[0] #resize and convert into the best pixel format sws = SWScale(img_size[0], img_size[1], pixel_format, thumb_size[0], thumb_size[1], output_format) thumbnail = sws.scale(img) streams = [{ 'pix_fmt_in': output_format, 'width_in': thumb_size[0], 'height_in': thumb_size[1], 'codec': codec, 'frame_rate': (30, 1) }] writer = MediaWriter(output, streams, lib_opts={'compression_algo': 'lzw'}) writer.write_frame(img=thumbnail, pts=0, stream=0) writer.close()
def test_write_streams(tmp_path): from ffpyplayer.writer import MediaWriter from ffpyplayer.tools import get_supported_pixfmts, get_supported_framerates from ffpyplayer.pic import Image from ffpyplayer.tools import get_codecs fname = str(tmp_path / 'test_video.avi') lib_opts = {} codec = 'rawvideo' if 'libx264' in get_codecs(encode=True, video=True): codec = 'libx264' lib_opts = {'preset': 'slow', 'crf': '22'} w, h = 640, 480 out_opts = { 'pix_fmt_in': 'rgb24', 'width_in': w, 'height_in': h, 'codec': codec, 'frame_rate': (5, 1) } metadata = { 'title': 'Singing in the sun', 'author': 'Rat', 'genre': 'Animal sounds' } writer = MediaWriter(fname, [out_opts] * 2, fmt='mp4', width_out=w / 2, height_out=h / 2, pix_fmt_out='yuv420p', lib_opts=lib_opts, metadata=metadata) # Construct images size = w * h * 3 buf = bytearray([int(x * 255 / size) for x in range(size)]) img = Image(plane_buffers=[buf], pix_fmt='rgb24', size=(w, h)) buf = bytearray([int((size - x) * 255 / size) for x in range(size)]) img2 = Image(plane_buffers=[buf], pix_fmt='rgb24', size=(w, h)) for i in range(20): writer.write_frame(img=img, pts=i / 5., stream=0) # stream 1 writer.write_frame(img=img2, pts=i / 5., stream=1) # stream 2 writer.close()
def record_thread_run(self, filename): queue = self.image_queue recorder = None t0 = None last_t = None while self.record_state != 'stopping': item = queue.get() if item == 'eof': break img, metadata = item if recorder is None: try: self.setattr_in_kivy_thread('ts_record', clock()) t0 = metadata['t'] iw, ih = img.get_size() ipix_fmt = img.get_pixel_format() (ifmt, iw, ih, irate), (opix_fmt, ow, oh, orate) = \ self.compute_recording_opts(ipix_fmt, iw, ih) self.setattr_in_kivy_thread( 'metadata_record_used', VideoMetadata(opix_fmt, ow, oh, orate)) orate = Fraction(orate) if orate >= 1.: orate = Fraction(orate.denominator, orate.numerator) orate = orate.limit_denominator(2 ** 30 - 1) orate = (orate.denominator, orate.numerator) else: orate = orate.limit_denominator(2 ** 30 - 1) orate = (orate.numerator, orate.denominator) stream = { 'pix_fmt_in': ipix_fmt, 'pix_fmt_out': opix_fmt, 'width_in': iw, 'height_in': ih, 'width_out': ow, 'height_out': oh, 'codec': 'rawvideo', 'frame_rate': orate} recorder = MediaWriter(filename, [stream]) except Exception as e: self.exception(e) Clock.schedule_once(self.complete_stop) return Clock.schedule_once(self.complete_start) try: self.setattr_in_kivy_thread( 'size_recorded', recorder.write_frame(img, metadata['t'] - t0)) self.increment_in_kivy_thread('frames_recorded') except Exception as e: self.exception(e) self.increment_in_kivy_thread('frames_skipped') if recorder is not None: try: recorder.close() except Exception as e: self.exception(e) Clock.schedule_once(self.complete_stop)
video = './../video/1x01.mkv' save_dir = './../frame/1x01/' # create image w, h = 1280, 720 fmt = 'rgb24' codec = 'png' # we'll encode it using the tiff codec out_opts = { 'pix_fmt_in': fmt, 'width_in': w, 'height_in': h, 'frame_rate': (30, 1), 'codec': codec } player = MediaPlayer(video) val = '' while val != 'eof': frame, val = player.get_frame() if val != 'eof' and frame is not None: img, t = frame frame_file = 'frame' + str(int(t)) + '.png' file = save_dir + frame_file print(str(t)) buf = img.to_bytearray() img = Image(plane_buffers=[buf[0]], pix_fmt=fmt, size=(w, h)) writer = MediaWriter(file, [out_opts]) writer.write_frame(img=img, pts=0, stream=0) writer.close()
def main(_): with tf.Session() as sess: config = get_config(FLAGS) env = MyEnvironment(config) agent = Agent(config, env, sess) scale = 1 # 1. first probe file, get metadata in_file = config.input_name out_file = config.output_name convert_num = -1 ff_opts = { 'out_fmt': 'yuv444p', 'framedrop': False, 'an': True, 'sn': True, } player = MediaPlayer(in_file, ff_opts=ff_opts) # must wait for probe result, strange while player.get_metadata()['src_vid_size'] == (0, 0): time.sleep(0.01) meta = player.get_metadata() width = meta['src_vid_size'][0] height = meta['src_vid_size'][1] width_out = width * scale height_out = height * scale out_opts = { 'pix_fmt_in': 'yuv444p', 'pix_fmt_out': 'yuv420p', 'width_in': width_out, 'height_in': height_out, 'frame_rate': meta['frame_rate'], 'codec': 'libx264', #'acpect': '4:3', } lib_opts = { # config for BT.2020 HDR10 # 'x265-params': 'range=pc:colorprim=bt2020:transfer=smpte2084:colormatrix=bt2020nc:crf=15', # config for x264 to encode video 'x264-params': 'crf=15', } writer = MediaWriter(out_file, [out_opts], lib_opts=lib_opts, overwrite=True) frame_count = 0 start_timestamp = 0 while True: frame, val = player.get_frame() if val == 'eof': print('end of video') break elif frame is None: time.sleep(0.01) else: t1 = time.time() * 1000 img, t = frame if frame_count == 0: start_timestamp = t bufs = img.to_bytearray() assert len(bufs) >= 3 Y = np.frombuffer(bufs[0], dtype=np.uint8) U = np.frombuffer(bufs[1], dtype=np.uint8) V = np.frombuffer(bufs[2], dtype=np.uint8) input_YUV = cv2.merge([Y, U, V]) img = cv2.cvtColor(input_YUV, cv2.COLOR_YUV2RGB) img = np.array(img).reshape(height, width, 3) outputImg = agent.test_video(img) out = np.array(outputImg).reshape(height_out * width_out, 1, 3) YUV = cv2.cvtColor(out, cv2.COLOR_RGB2YUV) (Y, U, V) = cv2.split(YUV) bufs = [] bufs.append(Y.tobytes()) bufs.append(U.tobytes()) bufs.append(V.tobytes()) outputImg = Image(plane_buffers=bufs, pix_fmt='yuv444p', size=(width_out, height_out)) t = t - start_timestamp writer.write_frame(img=outputImg, pts=t, stream=0) t2 = time.time() * 1000 frame_count += 1 if (frame_count % 30 == 0): print('convert frame # ', frame_count) #print('--pts:', t) if frame_count >= convert_num > 0: break # if frame_count >= 1800: # break # print("time: ", time.time()*1000-tt) player.close_player() writer.close()