social media crossposting tool. 3rd time's the charm
mastodon misskey crossposting bluesky

convert videos to mp4 on bluesky side

zenfyr.dev 2755fa21 6eac056d

verified
Changed files
+29 -5
+7 -5
bluesky.py
···
created_records.append(new_post)
else: # video is guarantedd to be one
video_data = attachments[0]
-
assert attachment.bytes
+
assert video_data.bytes
-
video_io = attachment.bytes
-
if not video_io:
-
LOGGER.error("Skipping post_id '%s', failed to download attachment! File too large?", post.get_id())
-
return
+
video_io = video_data.bytes
+
probe = media_util.probe_bytes(video_bytes)
+
format_name = probe['format']['format_name']
+
if 'mp4' not in format_name.split(','):
+
LOGGER.error("Converting %s to mp4...", video_data.get_url())
+
video_io = media_util.convert_to_mp4(video_io)
metadata = video_data.create_meta(video_io)
if metadata.get_duration() > 180:
+22
media_util.py
···
return json.loads(proc.stdout)
+
def convert_to_mp4(video_bytes: bytes) -> bytes:
+
cmd = [
+
'ffmpeg',
+
'-i', 'pipe:0',
+
'-c:v', 'libx264',
+
'-crf', '30',
+
'-preset', 'slow',
+
'-c:a', 'aac',
+
'-b:a', '128k',
+
'-movflags', 'frag_keyframe+empty_moov+default_base_moof',
+
'-f', 'mp4',
+
'pipe:1'
+
]
+
+
proc = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+
out_bytes, err = proc.communicate(input=video_bytes)
+
+
if proc.returncode != 0:
+
raise RuntimeError(f"ffmpeg compress failed: {err.decode()}")
+
+
return out_bytes
+
def compress_image(image_bytes: bytes, quality: int = 90):
cmd = [
'ffmpeg',