diff --git a/convert_video.py b/convert_video.py index cbe6639..4f549b1 100644 --- a/convert_video.py +++ b/convert_video.py @@ -1,46 +1,76 @@ import logging import os - import cv2 - def convert_video(images_path, output_path, width, height, fps, stilltime): """ - Convert images in output_path into a mp4 file usine OpenCV. - :param images_path: - :param output_path: - :param images_path: - :param width: - :param height: - :return: + Convert images in output_path into a mp4 file using OpenCV. + :param images_path: Path to the directory containing input images + :param output_path: Path for the output video file + :param width: Width of the output video + :param height: Height of the output video + :param fps: Frames per second for the output video + :param stilltime: Duration (in seconds) each image should be displayed + :return: True if conversion was successful, False otherwise """ + logging.info(f"Starting video conversion. OpenCV version: {cv2.__version__}") + logging.info(f"Parameters: images_path={images_path}, output_path={output_path}, width={width}, height={height}, fps={fps}, stilltime={stilltime}") - # define a frame array + # Check if the output directory exists + output_dir = os.path.dirname(output_path) + if not os.path.exists(output_dir): + os.makedirs(output_dir) + logging.info(f"Created output directory: {output_dir}") + + # Define a frame array frame_array = [] - # list all files in images_path + # List all files in images_path files = [f for f in os.listdir(images_path) if os.path.isfile(os.path.join(images_path, f))] - # sort the files files.sort() + logging.info(f"Found {len(files)} files in {images_path}") - # create a video writer object - - for i in range(len(files)): - file = os.path.join(images_path, files[i]) - logging.log(logging.INFO, f'Converting {file} to mp4') - img = cv2.imread(file) - for j in range(fps * stilltime): + # Read and process images + for i, file in enumerate(files): + file_path = os.path.join(images_path, file) + logging.info(f'Processing image {i+1}/{len(files)}: {file_path}') + img = cv2.imread(file_path) + if img is None: + logging.error(f"Failed to read image: {file_path}") + continue + if img.shape[:2] != (height, width): + logging.info(f"Resizing image from {img.shape[:2]} to {(height, width)}") + img = cv2.resize(img, (width, height)) + for _ in range(int(fps * stilltime)): frame_array.append(img) - fourcc = cv2.VideoWriter_fourcc(*'mp4v') - video_writer = cv2.VideoWriter(output_path, - fourcc, - fps, - (width, height)) + logging.info(f"Total frames to write: {len(frame_array)}") - for i in range(len(frame_array)): - # writing to a image array - video_writer.write(frame_array[i]) + # Create video writer + fourcc = cv2.VideoWriter_fourcc(*'mp4v') + video_writer = cv2.VideoWriter(output_path, fourcc, fps, (width, height)) + + if not video_writer.isOpened(): + logging.error(f"Failed to open VideoWriter for {output_path}") + return False + + # Write frames + for i, frame in enumerate(frame_array): + video_writer.write(frame) + if i % 100 == 0: + logging.info(f"Wrote frame {i+1}/{len(frame_array)}") video_writer.release() - logging.log(logging.INFO, f'Finished converting {output_path}') + + # Verify output + if os.path.exists(output_path): + file_size = os.path.getsize(output_path) + logging.info(f'Finished converting. Output file: {output_path}, Size: {file_size} bytes') + if file_size > 1000: + return True + else: + logging.warning(f"Output file is suspiciously small: {file_size} bytes") + else: + logging.error(f"Output file was not created: {output_path}") + + return False \ No newline at end of file diff --git a/routers/format_styles.py b/routers/format_styles.py index 1a31172..94912e4 100644 --- a/routers/format_styles.py +++ b/routers/format_styles.py @@ -15,7 +15,7 @@ router = APIRouter() @router.get("/styles/") async def get_styles(current_user: Annotated[User, Depends(get_current_active_user)]): - styles = Styles(styles=list_dir("{os.getcwd()}/styles")) + styles = Styles(styles=list_dir(f"{os.getcwd()}/styles")) return styles @router.get("/formats/{style}/") diff --git a/routers/generer.py b/routers/generer.py index 87363ee..74a5f28 100644 --- a/routers/generer.py +++ b/routers/generer.py @@ -60,7 +60,7 @@ async def generer(specs: DocumentSpecs, background_tasks: BackgroundTasks, curre pdf_file_path = f"{output_dir}/{base_name}.pdf" markdown_file_path = f"{output_dir}/{base_name}.md" latex_file_path = f"{output_dir}/{base_name}.tex" - images_path = f"{output_dir}/{base_name}_images" + images_path = f"{output_dir}/images" video_file_path = f"{output_dir}/{base_name}.mp4" try: @@ -107,13 +107,23 @@ async def generer(specs: DocumentSpecs, background_tasks: BackgroundTasks, curre # Generate MP4 video logger.info("Generating MP4 video...") - convert_video(images_path=images_path, - output_path=video_file_path, - width=specs.paperwidth, - height=specs.paperheight, - fps=specs.fps, - stilltime=specs.stilltime) - logger.info(f"MP4 video generated: {video_file_path}") + try: + success = convert_video( + images_path=images_path, + output_path=video_file_path, + width=specs.paperwidth, + height=specs.paperheight, + fps=specs.fps, + stilltime=specs.stilltime + ) + if success: + logger.info(f"MP4 video generated: {video_file_path}") + else: + logger.error(f"Failed to generate MP4 video: {video_file_path}") + raise Exception("Video generation failed") + except Exception as e: + logger.exception(f"Error during video generation: {str(e)}") + raise HTTPException(status_code=500, detail=f"Video generation failed: {str(e)}") # Create ZIP file zip_file_path = f"{output_dir}/{base_name}.zip" diff --git a/routers/images.py b/routers/images.py index 31b68be..bbc79f5 100644 --- a/routers/images.py +++ b/routers/images.py @@ -12,14 +12,14 @@ router = APIRouter() @router.get("/") async def get_images(current_user: Annotated[User, Depends(get_current_active_user)]): # list all files in resources/images - files = [f for f in os.listdir("../resources/images") if os.path.isfile(os.path.join("../resources/images", f))] + files = [f for f in os.listdir(f"{os.getcwd()}/resources/images") if os.path.isfile(os.path.join(f"{os.getcwd()}/resources/images", f))] # sort the files files.sort() return {"images": files} @router.get("/{nom_image}") async def get_image(nom_image: str, current_user: Annotated[User, Depends(get_current_active_user)]): - return FileResponse(f"./resources/images/{nom_image}") + return FileResponse(f"{os.getcwd()}/resources/images/{nom_image}") @router.post("/") async def ajouter_image(file: UploadFile, current_user: Annotated[User, Depends(get_current_active_user)]):