force_original_aspect_ratio='decrease').filter_( "pad", **PAD), ffmpeg.input('video_test/3.jpeg', loop=1, t=4).filter('scale', size='768:600', force_original_aspect_ratio='decrease').filter_( "pad", **PAD), ffmpeg.input('video_test/4.jpeg', loop=1, t=6).filter('scale', size='768:600', force_original_aspect_ratio='decrease').filter_( "pad", **PAD), ) time = 0 for e in rawImgSeq[0:1]: if e.get('a') == 'start': time = float(e.get('t')) stream = ffmpeg.drawbox(stream, (e.get('p')['x']) * 768, (e.get('p')['y']) * 600, 40, 40, color='[email protected]', thickness=40, enable=f'between(t,{time},{time+1})') # .filter('scale', "'min(600,iw)':min'(600,ih)':force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2") stream = ffmpeg.output(stream, 'video_test/out.mp4') stream = ffmpeg.overwrite_output(stream) ffmpeg.run(stream)
def upload_endpoint(): if 'uid' not in session: return '', 401 cover, audio = request.files.get('cover'), request.files.get('audio') title, dist_type = request.form.get('title'), request.form.get('dtype', type=int) start, end = request.form.get('start', type=float), request.form.get('end', type=float) if cover is None: return jsonify(message='Missing image in the request'), 400 if audio is None: return jsonify(message='Missing audio in the request'), 400 if cover.filename == '' or audio.filename == '': return jsonify(message='No file chosen'), 400 if title is None: return jsonify(message='No title provided'), 400 if dist_type is None: return jsonify(message='No distribution type specified'), 400 if start is None or end is None: return jsonify(message='Demo segement not specified'), 400 regex = re.compile(r'{}(.*)$'.format(FLASK_STATIC_FOLDER)) ext = cover.filename.rsplit('.', 1)[-1].lower() if ext in ['jpg', 'jpeg', 'png', 'gif']: filename = f'{int(datetime.timestamp(datetime.now()))}-{secure_filename(cover.filename)}' path = os.path.join(app.config['UPLOAD_FOLER'], filename) cover.save(path) cover = regex.match(path).group(1) else: return jsonify(message='File format error'), 400 ext = audio.filename.rsplit('.', 1)[-1].lower() if ext in ['mp3', 'wav']: ts = int(datetime.timestamp(datetime.now())) filename = secure_filename(audio.filename) path = os.path.join(app.config['UPLOAD_FOLER'], f'{ts}-{filename}') audio.save(path) audio = path path = os.path.join(app.config['UPLOAD_FOLER'], f'{ts}-demo-{filename}') demo = ffmpeg.input(audio, ss=start, t=end - start) demo = ffmpeg.output(demo, path) ffmpeg.run(demo) audio = regex.match(audio).group(1) demo = regex.match(path).group(1) else: return jsonify(message='File format error'), 400 r = requests.post(f'http://{DB_SERVER}/create-media', json={ 'title': title, 'full_audio': audio, 'demo_segment': demo, 'cover': cover, 'dist_type': bool(dist_type), 'uid': session['uid'] }) if r.status_code == 400: return jsonify(r.json()) if len(r.text) > 0 else '', 400 return jsonify( status=True, mid=r.json()['mid'], message='Your music has been successfully uploaded to our platform!', redirect='/'), 200
def flip_videos(): """ Flip the videos horizontally for given class and copy tags of selected original videos for flipped version of it. """ data = request.json project = data['projectName'] path = project_utils.lookup_project_path(project) config = project_utils.load_project_config(path) counterpart_class_name = str(data['counterpartClassName']) original_class_name = str(data['originalClassName']) copy_video_tags = data['videosToCopyTags'] if counterpart_class_name not in config['classes']: config['classes'][counterpart_class_name] = config['classes'][original_class_name] \ if copy_video_tags['train'] or copy_video_tags['valid'] else [] project_utils.write_project_config(path, config) for split in SPLITS: videos_path_in = os.path.join(path, f'videos_{split}', original_class_name) videos_path_out = os.path.join(path, f'videos_{split}', counterpart_class_name) original_tags_path = os.path.join(path, f'tags_{split}', original_class_name) counterpart_tags_path = os.path.join(path, f'tags_{split}', counterpart_class_name) # Create directory to save flipped videos os.makedirs(videos_path_out, exist_ok=True) os.makedirs(counterpart_tags_path, exist_ok=True) video_list = [video for video in os.listdir(videos_path_in) if video.endswith(VIDEO_EXT)] for video in video_list: output_video_list = [op_video for op_video in os.listdir(videos_path_out) if op_video.endswith(VIDEO_EXT)] print(f'Processing video: {video}') if '_flipped' in video: flipped_video_name = ''.join(video.split('_flipped')) else: flipped_video_name = video.split('.')[0] + '_flipped' + VIDEO_EXT if flipped_video_name not in output_video_list: # Original video as input original_video = ffmpeg.input(os.path.join(videos_path_in, video)) # Do horizontal flip flipped_video = ffmpeg.hflip(original_video) # Get flipped video output flipped_video_output = ffmpeg.output(flipped_video, filename=os.path.join(videos_path_out, flipped_video_name)) # Run to render and save video ffmpeg.run(flipped_video_output) # Copy tags of original video to flipped video (in train/valid set) if video in copy_video_tags[split]: original_tags_file = os.path.join(original_tags_path, video.replace(VIDEO_EXT, '.json')) flipped_tags_file = os.path.join(counterpart_tags_path, flipped_video_name.replace(VIDEO_EXT, '.json')) if os.path.exists(original_tags_file): with open(original_tags_file) as f: original_video_tags = json.load(f) original_video_tags['file'] = flipped_video_name with open(flipped_tags_file, 'w') as f: f.write(json.dumps(original_video_tags, indent=2)) print("Processing complete!") return jsonify(status=True, url=url_for("project_details", project=project))
"""Script for pulling images from a video stream via URL (like a Surfline cam rewind)""" import os import time import requests import ffmpeg TIMESTAMP = int(time.time()) DATA_DIR = os.path.dirname(__file__) URL = "https://camrewinds.cdn-surfline.com/live/wc-southoceanbeach.stream.20191125T201826428.mp4" SPOT_ID = "20191125T201826428" ffmpeg_fileformat = os.path.join(DATA_DIR, f"images/{TIMESTAMP}_{SPOT_ID}_%02d.jpg") stream = ffmpeg.input(URL, t=30) stream = ffmpeg.filter(stream, 'fps', fps=1, round='down') stream = ffmpeg.output(stream, ffmpeg_fileformat) stream.run() print("Complete")
def convert_video2image(v_path, out_dir): out_path = "{}/image%04d.png".format(out_dir) stream = ffmpeg.input(v_path) stream = ffmpeg.output(stream, out_path, r=5, vf="scale=684:504") ffmpeg.run(stream)
########## Convert files to .mp4 ########## for file in files: if file[-4:] != '.mp4': if file[-4:] not in ['.avi', '.flv', '.mov', '.mpeg', '.wmv']: continue input_video = ffmpeg.input(os.path.join(video_folder_path, file)) dot_index = video.rfind('.') raw_filename = video[0:dot_index] filename = raw_filename i = 1 while os.path.isfile(os.path.join(video_folder_path, filename) + '.mp4'): i += 1 filename = raw_filename + '(' + str(i) + ')' ffmpeg.output(input_video, os.path.join(video_folder_path, filename) + '.mp4').run() mp4_files.append(filename + '.mp4') else: mp4_files.append(file) ########## Copy files into dataset ########## for file in mp4_files: video_string = file dot_index = video_string.rfind('.') video_string = video_string[0:dot_index] filename = video_string + '.mp4' i = 0 while os.path.isfile('static/datasets/video/' + filename): i += 1 filename = video_string + '(' + str(i) + ').mp4'
def combine_compress_and_rename_videos_in_folder(folder=None, scale=None, fps=None): if folder is None: print('No folder. return.') return videos_to_process = [] for subdir, dirs, files in os.walk(folder): for file in sorted(files): print(f'file: {file}') regex_match = re.match(r"(.*_)(\d{4})_(\d{3})\.mp4", file, re.I) if regex_match: print('matched regex 1.') prefix = regex_match.group(1) video_number = regex_match.group(2) chapter = regex_match.group(3) else: regex_match = re.match(r"(GP|GH)(\d{2})(\d{4})\.mp4", file, re.I) if regex_match: print('matched regex 2') prefix = regex_match.group(1) video_number = regex_match.group(3) chapter = regex_match.group(2) else: print('did NOT match regex. continue..') continue dic = FileRepresentation() dic.prefix = prefix dic.video_number = video_number dic.chapter = chapter dic.filename = file dic.folder = folder dic.filepath = folder + '/' + file print(dic) videos_to_process.append(dic) print('organize into files to combine..') organized = OrderedDict() for dic in videos_to_process: unique_video_key = (dic.prefix, dic.video_number) organized.setdefault(unique_video_key, []) organized[unique_video_key].append(dic) print('done organizing files to combine.') print('running ffmpeg on files..') for unique_video_key in organized: print(f'unique_video_key: {unique_video_key}') files_to_combine = [] for dic in organized[unique_video_key]: files_to_combine.append(dic.filepath) print(f'files_to_combine: {files_to_combine}') ffmpeg_inputs = [] for file in files_to_combine: ffmpeg_inputs.append(ffmpeg.input(file)) ffmpeg_inputs.append(ffmpeg.input(file)) d = {'a': 1, 'v': 1} joined = ffmpeg.concat(*ffmpeg_inputs, **d) if scale is not None: joined = ffmpeg.filter(joined, 'scale', size=scale, force_original_aspect_ratio='decrease') if fps is not None: joined = ffmpeg.filter(joined, 'fps', fps=fps, round='up') dic = organized[unique_video_key][0] out_path = dic.folder + '/' + dic.prefix + dic.video_number + '_combined.mp4' out_stream = ffmpeg.output(joined, out_path) out_stream.run()
def _prep_data_worker(self, start, end, filenames): session = self.DBSession() i = start total_writes = 0 while i < end: print('{}: {}/{}'.format(filenames[i], i - start, end - start)) extract_path = os.path.join(self.extract_root, filenames[i].replace(" ", "_")) os.makedirs(extract_path, exist_ok=True) try: with zipfile.ZipFile(os.path.join(self.beatmaps_root, filenames[i]), "r") as zip_ref: zip_info = zip_ref.infolist() beatmap_list = [] # search for all beatmap files for info in zip_info: if '.osu' in info.filename: # extract beatmap data = zip_ref.read(info) bmfile_path = os.path.join(extract_path, os.path.basename(info.filename)) bmfile = open(bmfile_path, 'wb') bmfile.write(data) bmfile.close() # read the beatmap to find related audio file try: file = open(bmfile_path) p = pyttanko.parser() bmap = p.map(file) audio_file_name = bmap.audio_filename.strip().lower() audio_path = os.path.join(extract_path, audio_file_name) wave_filepath = audio_path + '.wav' for jifo in zip_info: if jifo.filename.lower() == audio_file_name and not os.path.isfile( os.path.join(extract_path, audio_file_name)): # extract audio for beatmap data = zip_ref.read(jifo) audio = open(audio_path, 'wb') audio.write(data) audio.close() # convert to wav stream = ffmpeg.input(audio_path) stream = ffmpeg.output(stream, wave_filepath, ac=1) ffmpeg.run(stream, quiet=True, overwrite_output=True) # calculate difficulty if bmap.mode == 0: file = open(bmfile_path) p = pyttanko.parser() bmap = p.map(file) diff = pyttanko.diff_calc().calc(bmap) file.close() # save metadata to mysql db date = datetime.datetime(*info.date_time[0:6]) new_bm_metadata = BeatmapMetadata(bmFilePath=bmfile_path, audioFilePath=wave_filepath, gamemodeType=bmap.mode, difficulty=diff.total, dateCreated=date) session.add(new_bm_metadata) except Exception as e: print("error parsing beatmap or audiofile, deleting beatmap: ", e) os.remove(bmfile_path) except(zipfile.BadZipFile): print("Bad zipfile: ", filenames[i]) i += 1 session.commit()
nargs='*') parser.add_argument('-o', dest='output', help='file to output the new video to.') args = parser.parse_args() output_file = args.output file_list = args.input ffmpeg_inputs = list() for file in file_list: ffmpeg_input = ffmpeg.input(file) ffmpeg_inputs.append(ffmpeg_input['v']) ffmpeg_inputs.append(ffmpeg_input['a']) #probe = ffmpeg.probe(file) #video_stream = next((stream for stream in probe['streams'] if stream['codec_type'] == 'video'), None) #pprint(video_stream['tags']['creation_time']) joined = ffmpeg.concat(*ffmpeg_inputs, v=1, a=1).node v = joined[0] a = joined[1] out = ffmpeg.output(v, a, output_file, vcodec="h264_nvenc", preset="default", pixel_format="yuva444p", video_bitrate="30M", bufsize="30M") out.run()
# import cv2 # # vcap = cv2.VideoCapture("rtsp://*****:*****@192.168.10.86:554/h264") # # while(1): # # ret, frame = vcap.read() # cv2.imshow('VIDEO', frame) # cv2.waitKey(1) import ffmpeg stream = ffmpeg.input('rtsp://*****:*****@192.168.10.30:554/h264', ss=0) # # stream2 = ffmpeg.filter_(stream1,'drawtext',text="%{pts}",box='1', boxcolor='0x00000000@1', fontcolor='white') # stream_out = ffmpeg.output(stream, 'output6.mp4') # ffmpeg.run(stream3) input = ffmpeg.input('rtsp://*****:*****@192.168.10.30:554/h264') # audio = input.audio.filter("aecho", 0.8, 0.9, 1000, 0.3) out = ffmpeg.output(input, 'out.mp4') ffmpeg.view(input)
def convert_video(source: str, dest: str): stream = ffmpeg.input(source) stream = ffmpeg.output(stream, dest, vcodec='libx265', crf='28') ffmpeg.run(stream)
for url_item in urls_data: try: # /* DownLoad Video & Audio List */ print("Video Path : ", url_item["Video_URL"]) print("Downloading Video...") video_request = requests.get(url_item["Video_URL"]) video_file = download_dir + 'video.' + url_item["Video_URL"].rsplit( '.', 1)[1] open(video_file, 'wb').write(video_request.content) print("Audio Path : ", url_item["Audio_URL"]) print("Downloading Audio...") audio_request = requests.get(url_item["Audio_URL"]) audio_file = download_dir + 'audio.' + url_item["Audio_URL"].rsplit( '.', 1)[1] open(audio_file, 'wb').write(video_request.content) # /* Combine Video & Audio List */ print("Combining Video and Audio...") video_stream = ffmpeg.input(video_file) audio_stream = ffmpeg.input(audio_file) ffmpeg.output(audio_stream, video_stream, result_dir + url_item["Result_Name"]).run() os.remove(video_file) os.remove(audio_file) print('END!') except Exception as err: print(err) continue
def convert_audio(path): input = ffmpeg.input(path) output = ffmpeg.output(input, f'{path}.wav', ar=16000) ffmpeg.run(output) os.remove(path)
def main(args): cos = create_cos_client(args) if not cos: raise ValueError(f"could not create COS instance") notification = args.get('notification', {}) key = args.get('key', notification.get('object_name', '')) # parse the key choir_id, song_id, def_id = Path(key).stem.split('-')[0].split('+') src_bucket = args['preprod_bucket'] dst_bucket = args['preview_bucket'] misc_bucket = args['misc_bucket'] definition_bucket = args['definition_bucket'] # Download the definition file for this job definition_key = f'{choir_id}+{song_id}+{def_id}.json' definition_object = cos.get_object( Bucket=definition_bucket, Key=definition_key, ) definition = json.load(definition_object['Body']) output_spec = definition['output'] geo = args['geo'] host = args.get('endpoint', args['ENDPOINT']) cos_hmac_keys = args['__bx_creds']['cloud-object-storage']['cos_hmac_keys'] cos_api_key = cos_hmac_keys['access_key_id'] cos_api_secret = cos_hmac_keys['secret_access_key'] get_input_url = partial(create_signed_url, host, 'GET', cos_api_key, cos_api_secret, geo, src_bucket) get_misc_url = partial(create_signed_url, host, 'GET', cos_api_key, cos_api_secret, geo, misc_bucket) ### ### Combine video and audio ### # Create a temp dir for our files to use with tempfile.TemporaryDirectory() as tmpdir: stream = ffmpeg.input(get_input_url(key), seekable=0, thread_queue_size=64) audio = stream.audio video = stream.video # Pad the video to final size, place video in center output_width, output_height = output_spec['size'] video = video.filter('pad', x=-1, y=-1, width=output_width, height=output_height) # Overlay the watermark if present watermark_file = output_spec.get('watermark') if watermark_file: watermark_url = get_misc_url(watermark_file) watermark = ffmpeg.input(watermark_url, seekable=0) video = video.overlay(watermark, x='W-w-20', y='H-h-20') print("Doing first pass loudnorm") stream = ffmpeg.input(get_input_url(key), seekable=0) audio = stream.audio audio = audio.filter('loudnorm', i=-14, dual_mono=True, print_format='json') pipeline = ffmpeg.output(audio, "-", format='null') cmd = pipeline.compile() print("ffmpeg command to run: ", cmd) stdout, stderr = pipeline.run(capture_stdout=True, capture_stderr=True) output = stdout + stderr output_lines = [line.strip() for line in output.decode().split('\n')] loudnorm_start = False loudnorm_end = False for index, line in enumerate(output_lines): if line.startswith('[Parsed_loudnorm'): loudnorm_start = index + 1 continue if loudnorm_start and line.startswith('}'): loudnorm_end = index + 1 break if not (loudnorm_start and loudnorm_end): raise Exception( "Could not parse loudnorm stats; no loudnorm-related output found" ) try: loudnorm_stats = json.loads('\n'.join( output_lines[loudnorm_start:loudnorm_end])) except Exception as e: raise Exception( "Could not parse loudnorm stats; wrong JSON format in string: {e}" ) print("json stats", loudnorm_stats) target_offset = float(loudnorm_stats['target_offset']) input_i = float(loudnorm_stats['input_i']) input_lra = float(loudnorm_stats['input_lra']) input_tp = float(loudnorm_stats['input_tp']) input_thresh = float(loudnorm_stats['input_thresh']) # Second pass, apply normalisation print("Doing second pass loudnorm") stream = ffmpeg.input(get_input_url(key), seekable=0) audio = audio.filter('loudnorm', i=-14, offset=target_offset, measured_i=input_i, measured_lra=input_lra, measured_tp=input_tp, measured_thresh=input_thresh, linear=True, print_format='summary') # Add in audio compression audio = audio.filter('acompressor') # Add reverb in if present reverb_type = output_spec.get('reverb_type') if reverb_type: reverb_url = get_misc_url(f'{reverb_type}.wav') reverb_pct = float(output_spec.get('reverb', 0.1)) if reverb_pct > 0: reverb_part = ffmpeg.input(reverb_url, seekable=0) split_audio = audio.filter_multi_output('asplit') reverb = ffmpeg.filter([split_audio[1], reverb_part], 'afir', dry=10, wet=10) audio = ffmpeg.filter([split_audio[0], reverb], 'amix', dropout_transition=180, inputs=2, weights=f'{1-reverb_pct} {reverb_pct}') # Output output_key = f'{choir_id}+{song_id}+{def_id}-final.mp4' output_path = str(Path(tmpdir, output_key)) kwargs = {} if 'duration' in args: kwargs['t'] = int(args['duration']) if 'loglevel' in args: kwargs['v'] = args['loglevel'] pipeline = ffmpeg.output(audio, video, output_path, pix_fmt='yuv420p', vcodec='libx264', preset='veryfast', movflags='+faststart', **kwargs) cmd = pipeline.compile() print("ffmpeg command to run: ", cmd) t1 = time.time() pipeline.run() t2 = time.time() # Upload the final file cos.upload_file(output_path, dst_bucket, output_key) ret = { 'dst_key': output_key, 'def_id': def_id, 'render_time': int(t2 - t1), 'status': 'ok' } return ret
import sys from goprocam import GoProCamera, constants import ffmpeg print("Run modprobe v4l2loopback device=1 video_nr=44 card_label=\"GoPro\" exclusive_caps=1") input("Hit enter when done!") gopro = GoProCamera.GoPro(ip_address=GoProCamera.GoPro.getWebcamIP( sys.argv[1]), camera=constants.gpcontrol, webcam_device=sys.argv[1]) gopro.webcamFOV(constants.Webcam.FOV.Wide) gopro.startWebcam() udp_stream = "udp://{}:8554".format(GoProCamera.GoPro.getWebcamIP(sys.argv[1])) stream = ffmpeg.input(udp_stream, vsync=2, fflags="nobuffer", flags="low_delay", probesize=3072) stream = ffmpeg.output(stream, "/dev/video44", ar="44100", vcodec='rawvideo', pix_fmt="yuv420p", format="v4l2") ffmpeg.run(stream) # "ExecStart=/usr/bin/ffmpeg -vsync 2 -fflags nobuffer -flags low_delay -probesize 3072 -nostdin -i udp://172.26.169.51:8554 -ar 44100 -f v4l2 -pix_fmt yuv420p -vcodec rawvideo /dev/video44" # Thanks to https://gist.github.com/andrewhowdencom/b7ed844ceb6fc44226974723abc7b2d1 # https://twitter.com/andrewhowdencom/status/1309153832350486529
for j in i.t_input_files: if (j.video_c == True): video = p.get_video_comp(j, i.t_num_inputs) if (video != None): input_videos.append(video) # if no file is running in a time interval, # create empty background of time interval's duration if (input_videos == None): sub_op_filepath = './temp/sub_op' + str(sub_op_id) + '.mp4' output = ffmpeg.output(base_image, sub_op_filepath).run() sub_input.append(sub_op_filepath) # else output or overlay elif (len(input_videos) == 1): sub_op_filepath = './temp/sub_op' + str(sub_op_id) + '.mp4' output = ffmpeg.output(input_videos[0], sub_op_filepath, **{ 'b:v': '48k' }).run() sub_input.append(sub_op_filepath) # for more than one input files
def generate_merge(self, paths, output_path, prefix='', merge_file_path=None): if merge_file_path is None: merge_file_path = self.generate_merge_file(paths, prefix) merge_input = ffmpeg.input(merge_file_path, f='concat', safe=0) return ffmpeg.output(merge_input, output_path, c='copy')
def normalize_movie(movie_path, fps, width, height): """ Normalize movie using resolution, width and height given in parameter. Generates a high def movie and a low def movie. """ folder_path = os.path.dirname(movie_path) file_source_name = os.path.basename(movie_path) file_target_name = "%s.mp4" % file_source_name[:-8] file_target_path = os.path.join(folder_path, file_target_name) low_file_target_name = "%s_low.mp4" % file_source_name[:-8] low_file_target_path = os.path.join(folder_path, low_file_target_name) (w, h) = get_movie_size(movie_path) resize_factor = w / h if width is None: width = math.floor(resize_factor * height) if width % 2 == 1: width = width + 1 if height % 2 == 1: height = height + 1 if not has_soundtrack(movie_path): _, _, err = add_empty_soundtrack(movie_path) else: err = None # High def version stream = ffmpeg.input(movie_path) stream = ffmpeg.output( stream.video, stream.audio, file_target_path, pix_fmt="yuv420p", format="mp4", r=fps, b="28M", preset="slow", vcodec="libx264", color_primaries=1, color_trc=1, colorspace=1, movflags="+faststart", s="%sx%s" % (width, height), ) stream.run(quiet=False, capture_stderr=True, overwrite_output=True) # Low def version low_width = 1280 low_height = math.floor((height / width) * low_width) if low_height % 2 == 1: low_height = low_height + 1 stream = ffmpeg.input(movie_path) stream = ffmpeg.output( stream.video, stream.audio, low_file_target_path, pix_fmt="yuv420p", format="mp4", r=fps, b="1M", preset="slow", vcodec="libx264", color_primaries=1, color_trc=1, colorspace=1, movflags="+faststart", s="%sx%s" % (low_width, low_height), ) stream.run(quiet=False, capture_stderr=True, overwrite_output=True) return file_target_path, low_file_target_path, err
def trim(start, end, path: str, copy: bool): if copy: new_input = ffmpeg.input(self.video_path, ss=start, to=end) return ffmpeg.output(new_input, path, c='copy') else: return ffmpeg.output(self.input_file, path, acodec=self.acodec, vcodec=self.vcodec, ss=start, to=end)
def run(self, output_dir, tags=[], start=0, end=None, exclude=None): if exclude is None: exclude = set() if tags is None: tags = [] outputs = [] audio_items = [] picture_outputs = [] csv_path = os.path.join(output_dir, "output.csv") with open(csv_path, 'w+', encoding='utf-8') as f: writer = csv.writer(f) for i, line in enumerate(self.preview()): line: PreviewItem start = line.from_time end = line.end_time if not i in exclude: name = generate_name(line.target_sub) audio_name = name + ".mp3" media_name = name + ".jpg" collection_dir = os.path.join(output_dir, "collection.media") if not os.path.exists(collection_dir): os.mkdir(collection_dir) loc = os.path.join(collection_dir, name + ".mp3") marker = self.sequence_marker(episode=1, sequence=i + 1, start=start) audio = self._input.audio.filter('atrim', start=start / 1000, end=end / 1000) out = ffmpeg.output(audio, loc).overwrite_output() audio_items.append({ "start": start, "end": end, "loc": loc, "media": self._media_file }) outputs.append(out) timestamp = start writer.writerow([ marker, '[sound:{}]'.format(audio_name), '<img src="{}">'.format(media_name), line.target_sub, line.native_sub, "tags:" + " ".join(tags) ]) loc_pic = os.path.join(collection_dir, media_name) picture_output = ffmpeg.input( self._media_file, ss=start / 1000).output( loc_pic, vframes=1, format='image2', vcodec='mjpeg').overwrite_output() picture_outputs.append(picture_output) total = len(outputs) + len(picture_outputs) total_audio = len(outputs) def do_audio(item): media_file = item["media"] loc = item["loc"] start = item["start"] end = item["end"] inp = ffmpeg.input(media_file) audio = inp.audio.filter('atrim', start=start / 1000, end=end / 1000) out = ffmpeg.output(audio, loc, loglevel='quiet').overwrite_output() out.run() def do_image(item): media_file = item["media"] loc = item["loc"] start = item["start"] end = item["end"] file, _ = os.path.splitext(loc) loc = "{}.jpg".format(file) output = ffmpeg.input(self._media_file, ss=start / 1000)\ .output( loc, vframes=1, format='image2', vcodec='mjpeg', loglevel='quiet').overwrite_output() output.run() def produce_audio(q): for i, o in enumerate(audio_items): q.put(o) yield ("audio", i + 1, total) def produce_image(q): for i, o in enumerate(audio_items): q.put(o) yield ("picture", total_audio + i + 1, total) for r in do_worker_pool(10, do_audio, produce_audio): yield r print("start image") for r in do_worker_pool(10, do_image, produce_image): yield r
def convert( output_type: str, input_video_url: typing.Optional[str] = None, input_audio_url: typing.Optional[str] = None ) -> typing.Optional[bytes]: try: if output_type == constants.OutputType.AUDIO: return (ffmpeg.input(input_audio_url).output( 'pipe:', format='opus', strict='-2').run(capture_stdout=True))[0] elif output_type == constants.OutputType.VIDEO: if input_audio_url is None: return (ffmpeg.input(input_video_url).output( 'pipe:', format='mp4', movflags='frag_keyframe+empty_moov', strict='-2').run(capture_stdout=True))[0] else: input_video = ffmpeg.input(input_video_url) input_audio = ffmpeg.input(input_audio_url) return (ffmpeg.output(input_video, input_audio, 'pipe:', format='mp4', movflags='frag_keyframe+empty_moov', strict='-2').run(capture_stdout=True))[0] elif output_type == constants.OutputType.VIDEO_NOTE: # Copied from https://github.com/kkroening/ffmpeg-python/issues/184#issuecomment-504390452. ffmpeg_input = (ffmpeg.input(input_video_url, t=constants.MAX_VIDEO_NOTE_LENGTH)) ffmpeg_input_video = (ffmpeg_input.video.crop( constants.VIDEO_NOTE_CROP_OFFSET_PARAMS, constants.VIDEO_NOTE_CROP_OFFSET_PARAMS, constants.VIDEO_NOTE_CROP_SIZE_PARAMS, constants.VIDEO_NOTE_CROP_SIZE_PARAMS)) ffmpeg_output: ffmpeg.nodes.OutputStream if has_audio_stream(input_video_url): ffmpeg_input_audio = ffmpeg_input.audio ffmpeg_joined = ffmpeg.concat(ffmpeg_input_video, ffmpeg_input_audio, v=1, a=1).node ffmpeg_output = ffmpeg.output( ffmpeg_joined[0], ffmpeg_joined[1], 'pipe:', format='mp4', movflags='frag_keyframe+empty_moov', strict='-2') else: ffmpeg_joined = ffmpeg.concat(ffmpeg_input_video, v=1).node ffmpeg_output = ffmpeg.output( ffmpeg_joined[0], 'pipe:', format='mp4', movflags='frag_keyframe+empty_moov', strict='-2') return ffmpeg_output.run(capture_stdout=True)[0] elif output_type == constants.OutputType.FILE: return (ffmpeg.input(input_audio_url).output( 'pipe:', format='mp3', strict='-2').run(capture_stdout=True))[0] except ffmpeg.Error as error: logger.error(f'ffmpeg error: {error}') return None
def start_streams(self): # base source of video of camera # video was too late and after audio # fixed via nobuffer making video earlier https://stackoverflow.com/a/49273163 source = ffmpeg.input('pipe:', format='h264', **{ 'r': self.camera_configuration.get_framerate(), 'thread_queue_size': 20480, 'fflags': 'nobuffer' }) audio = None if self.feature_states.get_STREAMING()[1]: # mic should be active # using nobuffer for same low latency as video # then applying async methods as in https://lzone.de/blog/Easily-fix-async-video-with-ffmpeg to sync audio to video audio = ffmpeg.input( self.camera_configuration.get_mic_input(), format='alsa', **{ 'ac': 1, "c:a": "pcm_s24le", "sample_rate": 192000, 'thread_queue_size': 20480, 'fflags': 'nobuffer', 'async': 1 } ) # reduce latency with no buffer then sync to video via async 1 # not needed and inacurate because changes 'itsoffset': MIC_OFFSET elif self.feature_states.get_STREAMING()[2]: # radio should be active audio = ffmpeg.input( self.camera_configuration.get_radio_url(), **{ 'ac': 2, 'itsoffset': RADIO_OFFSET, 'thread_queue_size': 20480 }) # only video no audio to ml stream if audio is not None: ml_output_stream = ffmpeg.output( source, audio, self.camera_configuration.get_object_recognition_stream_url(), format='rtsp', **{ 'fflags': 'nobuffer', 'threads': 2, # copy of normal streaming audio output 'acodec': 'aac', 'ac': 1, 'ar': 44100, 'ab': '128k', 'af': 'highpass=200,lowpass=2100,volume=4,loudnorm', 'vcodec': 'copy', 'reconnect': 1, 'reconnect_at_eof': 1, 'reconnect_streamed': 1, 'reconnect_delay_max': 30 }) else: ml_output_stream = ffmpeg.output( source, self.camera_configuration.get_object_recognition_stream_url(), format='rtsp', **{ 'fflags': 'nobuffer', 'threads': 2, 'vcodec': 'copy', 'reconnect': 1, 'reconnect_at_eof': 1, 'reconnect_streamed': 1, 'reconnect_delay_max': 30 }) stream_url = self.camera_configuration.get_stream_url() if audio is not None: # see these for audio implementation details since docs suck # https://github.com/kkroening/ffmpeg-python/issues/26 # https://github.com/kkroening/ffmpeg-python/pull/45#issue-159702983 streaming_output = ffmpeg.output( source, audio, stream_url, format='flv', **{ 'threads': 3, # audio high low filter here to reduce usb mic noise floor, then boost then normalize audio too # afftdn noise reduction filter seems to be problem and too much making stream unstable # ,afftdn 'acodec': 'aac', 'ac': 1, 'ar': 44100, 'ab': '128k', 'af': 'highpass=200,lowpass=2100,volume=4,loudnorm', 'vcodec': 'copy', 'reconnect': 1, 'reconnect_at_eof': 1, 'reconnect_streamed': 1, 'reconnect_delay_max': 30 }) else: streaming_output = ffmpeg.output( source, stream_url, format='flv', **{ 'threads': 3, # -acodec aac -ac 2 -ar 44100 -ab 128k 'vcodec': 'copy', 'reconnect': 1, 'reconnect_at_eof': 1, 'reconnect_streamed': 1, 'reconnect_delay_max': 30 }) stream = None if self.feature_states.get_OBJECT_DETECTION_STREAMING( ) and self.feature_states.get_STREAMING()[0]: # use almost recommmended way but not splititng and reencoding but merging output copy directly stream = ffmpeg.merge_outputs(streaming_output, ml_output_stream) elif self.feature_states.get_STREAMING()[0]: stream = streaming_output elif self.feature_states.get_OBJECT_DETECTION_STREAMING(): stream = ml_output_stream if stream is not None: self.any_video_running = True self.stream_runner_p = stream.run_async(pipe_stdin=True) print( "Starting pushing frames from camera into ffmpeg stream stdin..." ) self.camera.start_recording( self.stream_runner_p.stdin, format='h264', bitrate=self.camera_configuration.get_bitrate(), splitter_port=2 ) #splitter port to also circular record at same time else: pass
def video_from_sequence(input_dir, output_file, reference_file=None, ext=None, fps=None, bitrate=None, lossless=None): input_path = Path(input_dir) output_file_path = Path(output_file) reference_file_path = Path( reference_file) if reference_file is not None else None if not input_path.exists(): io.log_err("input_dir not found.") return if not output_file_path.parent.exists(): output_file_path.parent.mkdir(parents=True, exist_ok=True) return out_ext = output_file_path.suffix if ext is None: ext = io.input_str( "Input image format (extension)? ( default:png ) : ", "png") if lossless is None: lossless = io.input_bool("Use lossless codec ? ( default:no ) : ", False) video_id = None audio_id = None ref_in_a = None if reference_file_path is not None: if reference_file_path.suffix == '.*': reference_file_path = Path_utils.get_first_file_by_stem( reference_file_path.parent, reference_file_path.stem) else: if not reference_file_path.exists(): reference_file_path = None if reference_file_path is None: io.log_err("reference_file not found.") return #probing reference file probe = ffmpeg.probe(str(reference_file_path)) #getting first video and audio streams id with fps for stream in probe['streams']: if video_id is None and stream['codec_type'] == 'video': video_id = stream['index'] fps = stream['r_frame_rate'] if audio_id is None and stream['codec_type'] == 'audio': audio_id = stream['index'] if audio_id is not None: #has audio track ref_in_a = ffmpeg.input(str(reference_file_path))[str(audio_id)] if fps is None: #if fps not specified and not overwritten by reference-file fps = max(1, io.input_int("FPS ? (default:25) : ", 25)) if not lossless and bitrate is None: bitrate = max( 1, io.input_int("Bitrate of output file in MB/s ? (default:16) : ", 16)) input_image_paths = Path_utils.get_image_paths(input_path) i_in = ffmpeg.input('pipe:', format='image2pipe', r=fps) output_args = [i_in] if ref_in_a is not None: output_args += [ref_in_a] output_args += [str(output_file_path)] output_kwargs = {} if lossless: output_kwargs.update({"c:v": "png"}) else: output_kwargs.update({ "c:v": "libx264", "b:v": "%dM" % (bitrate), "pix_fmt": "yuv420p", }) output_kwargs.update({ "c:a": "aac", "b:a": "192k", "ar": "48000", "strict": "experimental" }) job = (ffmpeg.output(*output_args, **output_kwargs).overwrite_output()) try: job_run = job.run_async(pipe_stdin=True) for image_path in input_image_paths: with open(image_path, "rb") as f: image_bytes = f.read() job_run.stdin.write(image_bytes) job_run.stdin.close() job_run.wait() except: io.log_err("ffmpeg fail, job commandline:" + str(job.compile()))
def convert(name_vid, name_sound): audio = ffmpeg.input(name_vid).audio ffmpeg.output(audio, name_sound).run()
import ffmpeg input = ffmpeg.input('https://ma7moud3ly.github.io/video.mp4') hflip = input.hflip() vflip = input.vflip() ffmpeg.run(ffmpeg.output(hflip, 'hflip.mp4')) ffmpeg.run(ffmpeg.output(vflip, 'vflip.mp4'))
import ffmpeg #fadeout fadein file_path = "C:/Users/masho/Desktop/work/python/Python/lib/movie/Café_22728.mp4" #編集したい動画のパス save_path = "C:/Users/masho/Desktop/work/python/Python/lib/movie/sample.mp4" #トリミングしたい動画のパス #動画全体の時間を調べる video_info = ffmpeg.probe(file_path) duration = float(video_info['streams'][0]['duration']) #秒数抽出 divide_sec = duration stream = ffmpeg.input(file_path, ss=0, t=0) #音声取り出し audio_stream = stream.audio #開始から5秒かけてフェードインフェードアウト stream = stream.filter('fade', type='in', start_time=0, duration=2) stream = stream.filter('fade', type='out', start_time=duration - 2, duration=2) audio_stream = audio_stream.filter('afade', type='in', start_time=0, duration=2) stream = ffmpeg.output(stream, audio_stream, save_path) ffmpeg.run(stream)
import os import ffmpeg import speech_recognition as sr ###Hyper Paramaters### recog_audio_path = "./aps-smp.wav" input_name='00121' #動画の読み込み stream = ffmpeg.input(input_name+'.mp4') stream = ffmpeg.output(stream,'aps-smp.wav') stream = ffmpeg.overwrite_output(stream) stream.run() AUDIO_FILE = recog_audio_path # use the audio file as the audio source r = sr.Recognizer() with sr.AudioFile(AUDIO_FILE) as source: audio = r.record(source) # read the entire audio file result=r.recognize_google(audio, language='en-US') try: #print(AUDIO_FILE + ": \"" + result + "\n\n") except sr.UnknownValueError: print("AUDIO_FILE:Google Speech Recognition could not understand audio") except sr.RequestError as e: print("Could not request results from Google Speech Recognition service; {0}".format(e)) #テキストの保存
# ffmpeg-python import ffmpeg stream = ffmpeg.input('in.mp4') stream = ffmpeg.hflip(stream) stream = ffmpeg.output(stream, 'output.mp4') ffmpeg.run(stream) in_file = ffmpeg.input('in.mp4') overlay_file = ffmpeg.input('overlay.png') ( ffmpeg .concat( in_file.trim(start_frame=10, end_frame=20), in_file.trim(start_frame=30, end_frame=40), ) .overlay(overlay_file.hflip()) .drawbox(50, 50, 120, 120, color='red', thickness=5) .output('out.mp4') .run() )
import os import ffmpeg FILE_NAME = 'Shit Girls Say.mp4' OUT_DIR = os.path.join(os.getcwd(), 'output') # 入力 stream = ffmpeg.input(os.path.join(os.getcwd(), FILE_NAME)) stream = ffmpeg.output(stream, 'output.mov', t=1, ss=1) # 出力 # for i in range(68): # stream = ffmpeg.output(stream, str(i) + 'output.mov',t=i,ss=1) # 実行 ffmpeg.run(stream)