Search code examples
pythonfirebasevideocloudedit

add an audio to a video on Firebase using python


Simple and easy, or so I thought. Firebase seems to make it really hard to edit videos, it will work in the emulator but not when you deploy or vice versa. I've been trying to simply add an audio file to a video using a function. Right now the output is there but 0 bytes.

Right now this is my test functions for this specific example:

It will give you a link, and assuming you have the files video.mp4 and audio.mp3 inside of testfiles folder, it will upload them to the input bucket, then to the trigger bucket to run the function to add those 2 files and output them to the output bucket. But ffmpeg doesnt always work, moviepy also doesnt always work, plus its too slow.

def addTestBuckets2(req: https_fn.Request) -> https_fn.Response:

    # create the buckets
    testBucketInput = storage.bucket("testbucketinput")
    testBucketOutput = storage.bucket("testbucketoutput")
    testBucketTrigger = storage.bucket("testbuckettrigger")

    # upload the test files
    testBucketInput.blob("audio.mp3").upload_from_filename(
        "D:/backendfunctions/functions/testfiles/audio.mp3")
    testBucketInput.blob("video.mp4").upload_from_filename(
        "D:/backendfunctions/functions/testfiles/video.mp4")

    open("trigger.txt", "w").close()
    testBucketTrigger.blob("trigger.txt").upload_from_filename(
        "trigger.txt")

    # try to download the output.mp4 from the bucket on a loop
    keepTrying = 0
    while keepTrying < 100:
        try:
            testBucketOutput.blob("output.mp4").download_to_filename(
                "output.mp4")
            break
        except:
            sleep(.1)
            keepTrying += 1

    # os.remove("output.mp4")

    # return
    return https_fn.Response("Bucket tested")


@storage_fn.on_object_finalized(bucket="testbuckettrigger", region=region)
def editvidtestfunction(event: storage_fn.CloudEvent[storage_fn.StorageObjectData | None],) -> None:
    """ Test functions editing limit """

    # get the file path from the event
    file_path = event.data.name

    # get the file name
    file_name = file_path.split("/")[-1]
    # just_path = file_path.split("/")[:-1][0]
    # just_name = '.'.join(file_name.split('.')[:-1])

    # donwload the file from the bucket to local function
    storage.bucket("testbucketinput").blob(
        "video.mp4").download_to_filename("video.mp4")
    storage.bucket("testbucketinput").blob(
        "audio.mp3").download_to_filename("audio.mp3")

    # add the audio to the video using ffmpeg
    cmd = f"ffmpeg -i video.mp4 -i audio.mp3 -c copy -map 0:v:0 -map 1:a:0 output.mp4"
    subprocess.run(cmd, shell=True)

    # upload the final video to the output bucket
    storage.bucket("testbucketoutput").blob(
        "output.mp4").upload_from_filename("output.mp4")```

Solution

  • Firstly You will need to install the required packages in Python:

    pip install firebase-admin
    pip install google-cloud-storage
    

    Nextly setup your Firebase Admin SDK, create a new project if you do not have an existing one and generate a private key for that project which will be used in your python Code Then Upload your media to the Cloud Next process the media using Python Libraries, your can use Moviepy

    pip install moviepy
    

    Use the selected library to perform the required editing operations on the video and audio files. For example, you can concatenate audio files, overlay audio onto the video, or adjust timestamps as needed. Save your edited media file to the Cloud, don't forget to clean up after the process.

    import firebase_admin
    from firebase_admin import credentials
    from firebase_admin import storage
    from moviepy.editor import VideoFileClip, AudioFileClip
    
    # Step 2: Set up the Firebase Admin SDK
    cred = credentials.Certificate("path/to/serviceAccountKey.json")
    firebase_admin.initialize_app(cred, {
        'storageBucket': 'your-storage-bucket.appspot.com'
    })
    
    # Step 3: Upload your media files to Cloud Storage
    bucket = storage.bucket()
    video_blob = bucket.blob("videos/sample_video.mp4")
    audio_blob = bucket.blob("audios/sample_audio.wav")
    video_blob.upload_from_filename("path/to/sample_video.mp4")
    audio_blob.upload_from_filename("path/to/sample_audio.wav")
    
    # Step 4: Process the video and audio files
    video_path = video_blob.generate_signed_url(datetime.timedelta(seconds=1), method='GET')
    audio_path = audio_blob.generate_signed_url(datetime.timedelta(seconds=3), method='GET')
    video_clip = VideoFileClip(video_path)
    audio_clip = AudioFileClip(audio_path)
    final_clip = video_clip.set_audio(audio_clip)
    
    # Step 5: Save the edited media file
    final_clip.write_videofile("path/to/edited_video.mp4", codec="libx264")
    
    # Step 6: Clean up (optional)
    video_blob.delete()
    audio_blob.delete()
    

    In the code do the following Replacements "path/to/serviceAccountKey.json": The path to your Firebase service account key JSON file. "your-storage-bucket.appspot.com": Your Firebase Storage bucket name. "videos/sample_video.mp4": The desired location and filename for your video file in Cloud Storage. "audios/sample_audio.wav": The desired location and filename for your audio file in Cloud Storage. "path/to/sample_video.mp4": The local path to your video file. "path/to/sample_audio.wav": The local path to your audio file. "path/to/edited_video.mp4": The desired location and filename for the edited video file on your local machine.