File size: 3,523 Bytes
819e875
 
e04f2c1
819e875
34365ef
819e875
c246438
819e875
08eb9a4
819e875
34365ef
 
 
 
819e875
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e04f2c1
 
c50abfa
819e875
 
 
e04f2c1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68fb125
e04f2c1
 
 
 
 
 
 
 
 
68fb125
 
 
 
 
 
e04f2c1
 
 
819e875
 
e04f2c1
819e875
 
 
da9cb3e
34365ef
819e875
 
 
 
 
 
 
 
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
import streamlit as st
from pathlib import Path
import tempfile, subprocess, threading, queue
import textwrap
import streamlit.components.v1 as components

st.set_page_config(page_title="Lec2Note2 – Lecture-to-Notes", layout="wide")

st.title("πŸ“ Lec2Note – Automatic Lecture Notes Generator")

# Inject MathJax once for LaTeX rendering
MATHJAX = "<script src='https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js'></script>"
components.html(MATHJAX, height=0)

st.markdown(
    textwrap.dedent(
        """
        Upload a lecture **video** and receive a fully-formatted **Markdown** study note – complete with key images and structured sections.  
        The processing pipeline performs ASR transcription, vision & semantic segmentation, then invokes an LLM to produce rich notes.
        """
    )
)

video_file = st.file_uploader("🎬 Upload MP4/MKV/AVI", type=["mp4", "mkv", "avi"])

run_btn = st.button("πŸš€ Generate Notes", disabled=video_file is None)

if run_btn and video_file:
    # Save upload to a temporary file
    tmp_dir = tempfile.TemporaryDirectory()
    vid_path = Path(tmp_dir.name) / video_file.name
    with vid_path.open("wb") as f:
        f.write(video_file.read())

    output_md = vid_path.with_suffix(".md")

    st.info("Processing started. This may take several minutes depending on video length …")
    # container for live log streaming
    log_container = st.container()
    log_placeholder = log_container.code("", language="bash", height=300) 

    # Run pipeline via subprocess to avoid blocking UI; capture logs
    with st.spinner("Running Lec2Note2 pipeline …"):
        # launch pipeline in subprocess with unbuffered output
        cmd = [
            "python",
            "-u",  # unbuffer stdout
            "-m",
            "lec2note.scripts.run_pipeline",
            "--video",
            str(vid_path),
            "--output",
            str(output_md),
        ]
        proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)

        log_queue: "queue.Queue[str]" = queue.Queue()

        def _enqueue_output(pipe, q):
            for line in iter(pipe.readline, ""):
                q.put(line)
            pipe.close()

        threading.Thread(target=_enqueue_output, args=(proc.stdout, log_queue), daemon=True).start()

        logs = ""
        line_count = 0
        while True:
            try:
                line = log_queue.get(timeout=0.1)
            except queue.Empty:
                if proc.poll() is not None:
                    # process finished and queue empty
                    break
                continue
            logs += line
            line_count += 1
            if line_count % 5 == 0:  # update UI every 5 lines to reduce overhead
                log_placeholder.code(logs, language="bash", height=300)

        # final flush
        log_placeholder.code(logs, language="bash", height=300)

        result_code = proc.wait()
    if result_code != 0:
        st.error("❌ Pipeline failed. See logs below.")
        with st.expander("Show logs"):
            st.code(logs)
    else:
        st.success("βœ… Notes generated!")
        md_content = output_md.read_text()
        with st.container(border=True):
            st.markdown(md_content, unsafe_allow_html=True)
        st.download_button(
            label="πŸ’Ύ Download notes.md",
            data=md_content,
            file_name="lecture_notes.md",
            mime="text/markdown",
        )

    tmp_dir.cleanup()