File size: 6,905 Bytes
fbbd829
 
 
 
e9c3b30
4c27a39
 
67c3d30
 
fbbd829
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4c27a39
 
fbbd829
 
 
 
b9ff6ff
 
 
67c3d30
fbbd829
b9ff6ff
80406f2
b9ff6ff
80406f2
b9ff6ff
fbbd829
4c27a39
fbbd829
4c27a39
fecbcdf
fbbd829
 
4c27a39
 
fbbd829
 
e9c3b30
fecbcdf
e9c3b30
4c27a39
fbbd829
 
 
 
4ef1bcf
e2bf1ec
4c27a39
fbbd829
b9ff6ff
fbbd829
 
 
 
 
4c27a39
fbbd829
 
 
a0e8551
b9ff6ff
b3be269
120d9f7
 
 
 
a0e8551
 
 
120d9f7
fbbd829
 
 
fecbcdf
 
 
120d9f7
 
 
 
 
 
 
 
 
 
 
 
 
 
fbbd829
 
 
 
4c27a39
fbbd829
 
 
 
fecbcdf
 
 
 
 
 
 
 
 
 
 
4c27a39
fecbcdf
 
4c27a39
fecbcdf
 
b3be269
 
fecbcdf
 
 
 
 
4c27a39
e2bf1ec
fecbcdf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4c27a39
 
fecbcdf
 
 
 
 
 
 
 
 
 
 
4c27a39
 
 
 
e2bf1ec
4c27a39
 
 
fecbcdf
fbbd829
 
4c27a39
fbbd829
fecbcdf
 
 
 
 
 
 
fbbd829
 
 
 
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
import streamlit as st
from faster_whisper import WhisperModel
from moviepy.editor import VideoFileClip
import os
import traceback
from instagrapi import Client
from pathlib import Path
import torch
from transformers import AutoModelForSpeechSeq2Seq, AutoProcessor, pipeline

def convert_to_mp3(video_file):
    """Converts video to audio directly using `ffmpeg` command
    with the help of subprocess module"""
    video_clip = VideoFileClip(video_file)

    # Extract the audio from the video clip
    audio_clip = video_clip.audio

    # Write the audio to a separate file
    filename, ext = os.path.splitext(video_file)
    audio_clip.write_audiofile(filename + ".mp3")

    # Close the video and audio clips
    audio_clip.close()
    video_clip.close()

    os.remove(video_file)
    return filename + ".mp3"

@st.cache_resource
def get_model():
    model_size = "large-v3"
    model = WhisperModel(model_size, device="cuda", compute_type="float16")
    return model

def transcribe_audio(audio_file):
    model = get_model()
    st.info("transcribe_audio")
    segments, info = model.transcribe(audio_file, beam_size=1)
    st.info("transcribe_audio done..")
    return segments

def transcribe_post():
    file_name = None
    media_pk: str = None

    with st.spinner("Searching reel..."):
        try:
            media_pk = st.session_state.insta.media_pk_from_url(st.session_state.reel_id)
            if media_pk is None:
                st.warning("Invalid reel!")
        except Exception as e:
            st.error(traceback.format_exc())
            st.error("Cannot load post")

    if media_pk and not st.session_state.file_result:
        ok = False
        with st.spinner("Loading reel..."):
            try:
                # write to temp
                media_path:Path = st.session_state.insta.video_download(media_pk, "/data")
                file_name = "/data/" + media_path.name
                ok = True
            except Exception as e:
                st.error(traceback.format_exc())
                st.error("Cannot download reel!")
        if ok:
            file_name_audio = None
            with st.spinner("Extracting audio..."):
                file_name_audio = convert_to_mp3(file_name)
                st.session_state.file_result = file_name_audio + ".txt"
            st.success("Audio extracted!")

            with st.spinner("Final step: transcribing audio..."):
                try:
                    segments = transcribe_audio(file_name_audio)
                    st.info("Transcription done! Saving...")
                    st.session_state.file_transcript = "/data/" + st.session_state.file_result
                    with open(st.session_state.file_transcript, "w", encoding="utf-8") as f:
                        for segment in segments:
                            f.writelines("[" + str(segment.start) + "=>" + str(segment.end) + "]: " + segment.text)
                except Exception as e:
                    st.error(traceback.format_exc())
                    st.error("Cannot transcribe audio!")
            if not st.session_state.file_transcript:
                st.error("No transcription found!")
            else:
                st.balloons()

    if st.session_state.file_transcript and st.session_state.file_result:
        st.header('Results', divider='orange')
        data = ''
        try:
            with open(st.session_state.file_transcript, "r", encoding="utf-8") as f:
                data = f.read()
            # st.text_area("Transcript", data, disabled=True, height=300)
            st.download_button(
                label="Download transcript",
                data=data,
                file_name=st.session_state.file_result,
                mime="text/plain",
            )
        except Exception as e:
            st.error(traceback.format_exc())
            st.error("Cannot load transcript result!")

def load_profile(username):
    with st.spinner("Loading profile..."):
        try:
            st.session_state.profile = st.session_state.insta.user_info_by_username(username)
            st.info("Profile loaded!")
        except Exception as e:
            st.error("Profile not found!")

def exec_transcribe():
    if st.session_state.logged_in:
        st.header('Transcription', divider='violet')
        with st.container(border=True):
            target_user = st.text_input("Profile", placeholder="Enter target profile")
            if st.button("Check"):
                if target_user:
                    load_profile(target_user)
                else:
                    st.warning("Please enter username")
            if st.session_state.profile:
                reel_id = st.text_input("Enter reel url")
                if st.button("Transcribe"):
                    if not reel_id:
                        st.warning("Please enter reel url")
                    else:
                        st.session_state.reel_id = reel_id
            if st.session_state.reel_id:
                transcribe_post()

def login_user(username: str, password: str):
    if st.button("Login"):
        if username and password:
            with st.spinner("Logging in..."):
                st.session_state.insta.login(username, password)
                st.session_state.insta.dump_settings("/data/session.json")
                st.session_state.logged_in = True
        else:
            st.session_state.logged_in = False
            st.warning("Please enter username and password")


def initialize_app():
    st.set_page_config(
        page_title="Transcriber",
        page_icon="public/favicon.ico",
        menu_items={
            "About": "### Contact\n ✉️florinbobis@gmail.com",
        },
    )
    st.title("✍️Transcribe your reel")
    if not "insta" in st.session_state:
        st.session_state.insta = None
    if not "profile" in st.session_state:
        st.session_state.profile = None
    if not "logged_in" in st.session_state:
        st.session_state.logged_in = False
    if not "file_transcript" in st.session_state:
        st.session_state.file_transcript = None
    if not "file_result" in st.session_state:
        st.session_state.file_result = None
    if not "reel_id" in st.session_state:
        st.session_state.reel_id = None

def init_ig() -> Client:
    cl = Client()
    cl.delay_range = [1, 3]
    try:
        cl.load_settings("/data/session.json")
    except Exception as e:
        print(e)
    return cl

def main():
    initialize_app()
    st.session_state.insta = init_ig()

    st.header('IG Login', divider='blue')
    with st.container(border=True):
        username = st.text_input("Username", placeholder='Please enter your username')
        password = st.text_input("Password", type="password", placeholder='Please enter your password')
        login_user(username, password)

    exec_transcribe()


if __name__ == "__main__":
    main()