File size: 5,259 Bytes
bea535a
1b6025d
 
184a115
1b4da46
a7e2ea5
1b6025d
7211343
829b713
1b6025d
1b4da46
 
 
1b6025d
 
 
829b713
 
 
754a99d
be918f3
bea535a
1b6025d
be918f3
1b6025d
bea535a
184a115
bea535a
8f97db7
24edc06
bea535a
c99af6f
 
 
184a115
3dd7fad
 
184a115
 
754a99d
184a115
 
 
3dd7fad
754a99d
184a115
3dd7fad
184a115
 
 
754a99d
184a115
 
3dd7fad
1b4da46
184a115
 
3dd7fad
1b4da46
184a115
 
3dd7fad
1b4da46
184a115
754a99d
1b6025d
baf164e
018b6b4
3dd7fad
c99af6f
0057e73
c99af6f
 
3dd7fad
c99af6f
018b6b4
1b4da46
0057e73
7211343
 
 
3dd7fad
1b4da46
bf08b48
7211343
 
 
 
 
 
 
 
3dd7fad
1b4da46
7211343
 
a1a0ea8
7211343
 
3dd7fad
1b4da46
7211343
6bf70b2
7211343
 
1b4da46
3dd7fad
1b4da46
bea535a
 
 
 
1b6025d
 
 
 
a7e2ea5
 
 
1b6025d
 
e6db5f3
 
 
1b6025d
 
 
 
2c12c7a
1b6025d
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
from pydantic import BaseModel
from fastapi import FastAPI, UploadFile, HTTPException
from ffmpeg import input, output, run
from botocore.exceptions import ClientError
import logging
import ffmpeg
import boto3
import json
import os

logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)

app = FastAPI()

# Define your AWS S3 credentials and bucket name
aws_access_key_id = os.environ['AWS_ACCESS_KEY_ID']
aws_secret_access_key = os.environ['AWS_SECRET_ACCESS_KEY']
s3_bucket_name = os.environ['S3_BUCKET_NAME']
aws_env = os.environ['AWS_ENV']
aws_region = 'eu-central-1'
temp_dir = '/tmp/'
# Initialize an S3 client
s3_client = boto3.client('s3', aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key, region_name=aws_region)

class CutRequest(BaseModel):
    quote_filename: str
    segments: list[tuple[float, float]]
    news_name: str
    news_id: int

class CutRequestInput(BaseModel):
    data: CutRequest

def download_file(news_name: str, quote_filename: str, new_filename: str = "source.mp3"):
    # logger.debug(f"Downloading file: news_name={news_name}, quote_filename={quote_filename}")
    s3_directory = f'uploads/{aws_env}/{news_name}'
    s3_object_key = f'{s3_directory}/{quote_filename}'
    local_file = os.path.join(temp_dir, new_filename)

    try:
        # Ensure the download directory exists
        os.makedirs(temp_dir, exist_ok=True)
        # logger.debug(f"Downloading from S3: bucket={s3_bucket_name}, key={s3_object_key}, local_file={local_file}")

        s3_client.download_file(s3_bucket_name, s3_object_key, local_file)
        # logger.debug(f"File downloaded and saved as: {local_file}")
        
        # Return the local_file path
        return local_file

    except ClientError as e:
        if e.response['Error']['Code'] == "404":
            # logger.error(f"File not found in S3: {s3_object_key}")

            raise HTTPException(status_code=404, detail=f"The file {quote_filename} does not exist in S3.")
        else:
            # logger.error(f"S3 download error: {str(e)}")

            raise HTTPException(status_code=500, detail=f"Failed to download file from S3: {str(e)}")
    except Exception as e:
        # logger.exception(f"Unexpected error in download_file: {str(e)}")

        raise HTTPException(status_code=500, detail=f"An unexpected error occurred: {str(e)}")


@app.post("/cut-audio")
async def cut_audio(request: CutRequestInput):
    # logger.debug(f"Received request: {request}")

    try:
        
        cut_request = request.data
        # logger.debug(f"Parsed cut_request: {cut_request}")


        print(f"Received request: {cut_request}")

        download_file(cut_request.news_name, cut_request.quote_filename)
        for i, segment in enumerate(cut_request.segments):
            start, end = segment
            # logger.debug(f"Processing segment {i}: start={start}, end={end}")

            output_file = f"/tmp/cut_quote_{i}_{cut_request.quote_filename}"
            try:
                (
                    ffmpeg
                    .input('/tmp/source.mp3', ss=start, to=end)
                    .output(output_file)
                    .run()
                )
            except ffmpeg.Error as e:
                # logger.error(f"FFMPEG Error: {str(e)}")

                raise HTTPException(status_code=500, detail=str(e))
            try:
                s3_output_key = f'cut_outs/{aws_env}/{cut_request.news_id}/quote_segment_{i}.mp3'
                s3_client.upload_file(output_file, s3_bucket_name, s3_output_key)
            except Exception as e:
                # logger.error(f"S3 Upload Error: {str(e)}")

                raise HTTPException(status_code=500, detail=f"Failed to upload file to S3: {e}")

        return {"message": "Audio cut successfully"}
    
    except Exception as e:
        # logger.exception("Unexpected error in cut_audio")
        raise HTTPException(status_code=500, detail=f"Unexpected error: {str(e)}")

@app.post("/merge_audio/{output_key}")
async def merge_audio(output_key: str):
    s3_directory = output_key
    # Output file name
    output_file = temp_dir + 'output.mp3'

    # Use python-ffmpeg to merge audio clips
    # input_file_paths = [temp_dir + input_file for input_file in input_files]
    # input_args = [input(file_path) for file_path in input_file_paths]
    input_file = 'list.txt'

    try:
        intermediate_output = temp_dir + 'intermediate_output.mp3'
        ffmpeg.input(input_file, format='concat', safe=0).output(intermediate_output, c='copy').run()
        ffmpeg.input(intermediate_output).audio.filter('loudnorm').output(output_file, audio_bitrate='256k', ar='44100').run()
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"FFmpeg Error: {e}")

    # Upload the merged file back to S3
    s3_output_key = f'{s3_directory}/final.mp3'
    try:
        s3_client.upload_file(output_file, s3_bucket_name, s3_output_key)
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Failed to upload file to S3: {e}")

    return {"message": "Audio clips successfully merged and saved in S3"}

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=7680)