support video
This commit is contained in:
parent
96bfa4de97
commit
ba27d3fdbf
|
|
@ -117,11 +117,6 @@ async def s_api_v1_storage_get(request, file_hash=None):
|
||||||
# query_id = str(uuid4().hex())
|
# query_id = str(uuid4().hex())
|
||||||
tempfile_path = os.path.join(UPLOADS_DIR, f"tmp_{content_sha256}")
|
tempfile_path = os.path.join(UPLOADS_DIR, f"tmp_{content_sha256}")
|
||||||
|
|
||||||
# async def remove_temp_files():
|
|
||||||
# await asyncio.sleep(180)
|
|
||||||
# if os.path.exists(tempfile_path):
|
|
||||||
# os.remove(tempfile_path)
|
|
||||||
|
|
||||||
accept_type = cid.accept_type or content.meta.get("content_type")
|
accept_type = cid.accept_type or content.meta.get("content_type")
|
||||||
if accept_type:
|
if accept_type:
|
||||||
if accept_type == "application/json":
|
if accept_type == "application/json":
|
||||||
|
|
@ -141,7 +136,7 @@ async def s_api_v1_storage_get(request, file_hash=None):
|
||||||
quality = 95
|
quality = 95
|
||||||
while quality > 10:
|
while quality > 10:
|
||||||
cover_image.save(cover_tempfile_path, 'JPEG', quality=quality)
|
cover_image.save(cover_tempfile_path, 'JPEG', quality=quality)
|
||||||
if os.path.getsize(cover_tempfile_path) <= 200 * 1024: # Проверка размера файла в килобайтах
|
if os.path.getsize(cover_tempfile_path) <= 200 * 1024:
|
||||||
break
|
break
|
||||||
quality -= 5
|
quality -= 5
|
||||||
|
|
||||||
|
|
@ -160,6 +155,8 @@ async def s_api_v1_storage_get(request, file_hash=None):
|
||||||
audio = AudioSegment.from_ogg(file_path)
|
audio = AudioSegment.from_ogg(file_path)
|
||||||
elif file_ext == 'flv':
|
elif file_ext == 'flv':
|
||||||
audio = AudioSegment.from_flv(file_path)
|
audio = AudioSegment.from_flv(file_path)
|
||||||
|
else:
|
||||||
|
audio = None
|
||||||
|
|
||||||
if not audio:
|
if not audio:
|
||||||
try:
|
try:
|
||||||
|
|
@ -183,9 +180,10 @@ async def s_api_v1_storage_get(request, file_hash=None):
|
||||||
content_file_bin = await file.read()
|
content_file_bin = await file.read()
|
||||||
|
|
||||||
accept_type = 'audio/mpeg'
|
accept_type = 'audio/mpeg'
|
||||||
make_log(f"Storage", f"Audio {content_sha256} converted successfully")
|
make_log("Storage", f"Audio {content_sha256} converted successfully")
|
||||||
else:
|
else:
|
||||||
tempfile_path = tempfile_path[:-5]
|
tempfile_path = tempfile_path[:-5]
|
||||||
|
|
||||||
elif content_type == 'image':
|
elif content_type == 'image':
|
||||||
tempfile_path += "_jpeg"
|
tempfile_path += "_jpeg"
|
||||||
if not os.path.exists(tempfile_path):
|
if not os.path.exists(tempfile_path):
|
||||||
|
|
@ -195,7 +193,7 @@ async def s_api_v1_storage_get(request, file_hash=None):
|
||||||
quality = 95
|
quality = 95
|
||||||
while quality > 10:
|
while quality > 10:
|
||||||
image.save(tempfile_path, 'JPEG', quality=quality)
|
image.save(tempfile_path, 'JPEG', quality=quality)
|
||||||
if os.path.getsize(tempfile_path) <= 200 * 1024: # Проверка размера файла в килобайтах
|
if os.path.getsize(tempfile_path) <= 200 * 1024:
|
||||||
break
|
break
|
||||||
quality -= 5
|
quality -= 5
|
||||||
except BaseException as e:
|
except BaseException as e:
|
||||||
|
|
@ -205,13 +203,52 @@ async def s_api_v1_storage_get(request, file_hash=None):
|
||||||
async with aiofiles.open(tempfile_path, "rb") as file:
|
async with aiofiles.open(tempfile_path, "rb") as file:
|
||||||
content_file_bin = await file.read()
|
content_file_bin = await file.read()
|
||||||
|
|
||||||
make_log(f"Storage", f"Image {content_sha256} converted successfully")
|
make_log("Storage", f"Image {content_sha256} converted successfully")
|
||||||
accept_type = 'image/jpeg'
|
accept_type = 'image/jpeg'
|
||||||
else:
|
else:
|
||||||
tempfile_path = tempfile_path[:-5]
|
tempfile_path = tempfile_path[:-5]
|
||||||
|
|
||||||
return response.raw(body=content_file_bin, **({'content_type': accept_type} if accept_type else {}))
|
elif content_type == 'video':
|
||||||
|
# Build a temp path for the video
|
||||||
|
tempfile_path += "_mp4" + (f"_{seconds_limit}" if seconds_limit else "")
|
||||||
|
if not os.path.exists(tempfile_path):
|
||||||
|
try:
|
||||||
|
# Use ffmpeg to cut or convert to mp4
|
||||||
|
if seconds_limit > 0:
|
||||||
|
# Cut the video to the specified seconds_limit
|
||||||
|
subprocess.run([
|
||||||
|
"ffmpeg",
|
||||||
|
"-y",
|
||||||
|
"-i", file_path,
|
||||||
|
"-t", str(seconds_limit),
|
||||||
|
"-c:v", "libx264",
|
||||||
|
"-c:a", "aac",
|
||||||
|
"-movflags", "+faststart",
|
||||||
|
tempfile_path
|
||||||
|
], check=True)
|
||||||
|
else:
|
||||||
|
# Just convert to mp4 (no cutting)
|
||||||
|
subprocess.run([
|
||||||
|
"ffmpeg",
|
||||||
|
"-y",
|
||||||
|
"-i", file_path,
|
||||||
|
"-c:v", "libx264",
|
||||||
|
"-c:a", "aac",
|
||||||
|
"-movflags", "+faststart",
|
||||||
|
tempfile_path
|
||||||
|
], check=True)
|
||||||
|
except BaseException as e:
|
||||||
|
make_log("Storage", f"Error converting video: {e}" + '\n' + traceback.format_exc(), level="error")
|
||||||
|
|
||||||
|
if os.path.exists(tempfile_path):
|
||||||
|
async with aiofiles.open(tempfile_path, "rb") as file:
|
||||||
|
content_file_bin = await file.read()
|
||||||
|
make_log("Storage", f"Video {content_sha256} processed successfully")
|
||||||
|
accept_type = 'video/mp4'
|
||||||
|
else:
|
||||||
|
tempfile_path = tempfile_path[:-4] # remove _mp4 or similar suffix
|
||||||
|
|
||||||
|
return response.raw(body=content_file_bin, **({'content_type': accept_type} if accept_type else {}))
|
||||||
|
|
||||||
async def s_api_v1_storage_decode_cid(request, content_id=None):
|
async def s_api_v1_storage_decode_cid(request, content_id=None):
|
||||||
cid, errmsg = resolve_content(content_id)
|
cid, errmsg = resolve_content(content_id)
|
||||||
|
|
|
||||||
|
|
@ -87,6 +87,37 @@ class PlayerTemplates:
|
||||||
'text': self.user.translated('openContractPage_button'),
|
'text': self.user.translated('openContractPage_button'),
|
||||||
'url': f"https://tonscan.org/address/{content_meta['item_address']}"
|
'url': f"https://tonscan.org/address/{content_meta['item_address']}"
|
||||||
}])
|
}])
|
||||||
|
elif content_type == 'video':
|
||||||
|
# Processing video
|
||||||
|
video_title = content_metadata_json.get('name', "")
|
||||||
|
template_kwargs['video'] = URLInputFile(local_content_url)
|
||||||
|
template_kwargs['caption'] = video_title
|
||||||
|
template_kwargs['protect_content'] = True
|
||||||
|
|
||||||
|
if cover_content:
|
||||||
|
# Add thumbnail if cover content is available
|
||||||
|
template_kwargs['thumbnail'] = URLInputFile(cover_content.web_url)
|
||||||
|
|
||||||
|
if self.bot_id == 1:
|
||||||
|
# Buttons for sharing and opening in app
|
||||||
|
inline_keyboard_array.append([{
|
||||||
|
'text': self.user.translated('shareTrack_button'),
|
||||||
|
'switch_inline_query': f"C{content.cid.serialize_v2()}",
|
||||||
|
}])
|
||||||
|
inline_keyboard_array.append([{
|
||||||
|
'text': self.user.translated('openTrackInApp_button'),
|
||||||
|
'url': f"https://t.me/{CLIENT_TELEGRAM_BOT_USERNAME}/content?startapp={content.cid.serialize_v2()}"
|
||||||
|
}])
|
||||||
|
else:
|
||||||
|
# Buttons for viewing as a client and opening contract
|
||||||
|
inline_keyboard_array.append([{
|
||||||
|
'text': self.user.translated('viewTrackAsClient_button'),
|
||||||
|
'url': f"https://t.me/{CLIENT_TELEGRAM_BOT_USERNAME}?start=C{content.cid.serialize_v2()}"
|
||||||
|
}])
|
||||||
|
inline_keyboard_array.append([{
|
||||||
|
'text': self.user.translated('openContractPage_button'),
|
||||||
|
'url': f"https://tonscan.org/address/{content_meta['item_address']}"
|
||||||
|
}])
|
||||||
else:
|
else:
|
||||||
local_content = None
|
local_content = None
|
||||||
|
|
||||||
|
|
@ -104,7 +135,12 @@ class PlayerTemplates:
|
||||||
or bool(self.db_session.query(UserContent).filter_by(owner_address=user_wallet_address, status='active', content_id=content.id).first())
|
or bool(self.db_session.query(UserContent).filter_by(owner_address=user_wallet_address, status='active', content_id=content.id).first())
|
||||||
)
|
)
|
||||||
if not have_access:
|
if not have_access:
|
||||||
|
if content_type == 'audio':
|
||||||
|
# Restrict audio to 30 seconds if user does not have access
|
||||||
template_kwargs['audio'] = URLInputFile(local_content_url + '?seconds_limit=30')
|
template_kwargs['audio'] = URLInputFile(local_content_url + '?seconds_limit=30')
|
||||||
|
elif content_type == 'video':
|
||||||
|
# Restrict video to 30 seconds if user does not have access
|
||||||
|
template_kwargs['video'] = URLInputFile(local_content_url + '?seconds_limit=30')
|
||||||
|
|
||||||
make_log("TG-Player", f"Send content {content_type} ({content_encoding}) to chat {self._chat_id}. {cd_log}")
|
make_log("TG-Player", f"Send content {content_type} ({content_encoding}) to chat {self._chat_id}. {cd_log}")
|
||||||
for kmsg in self.db_session.query(KnownTelegramMessage).filter_by(
|
for kmsg in self.db_session.query(KnownTelegramMessage).filter_by(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue