From 6b48bd52b5e09b967508c8f3a4ebf981c7c7ed43 Mon Sep 17 00:00:00 2001 From: Mustafa Yontar Date: Fri, 30 Apr 2021 14:48:53 +0300 Subject: [PATCH] first commit --- .gitignore | 10 ++++ .idea/.gitignore | 8 +++ .idea/inspectionProfiles/Project_Default.xml | 26 ++++++++++ .../inspectionProfiles/profiles_settings.xml | 6 +++ .idea/misc.xml | 4 ++ .idea/modules.xml | 8 +++ .idea/tryCanvas.iml | 10 ++++ StreamMerger.py | 31 ++++++++++++ VideoFile.py | 43 ++++++++++++++++ __pycache__/StreamMerger.cpython-38.pyc | Bin 0 -> 1102 bytes __pycache__/VideoFile.cpython-38.pyc | Bin 0 -> 1485 bytes antonio.ttf | Bin 0 -> 73780 bytes main.py | 41 ++++++++++++++++ requirements.txt | 3 ++ stream.sh | 37 ++++++++++++++ testsup.py | 46 ++++++++++++++++++ 16 files changed, 273 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/.gitignore create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/tryCanvas.iml create mode 100644 StreamMerger.py create mode 100644 VideoFile.py create mode 100644 __pycache__/StreamMerger.cpython-38.pyc create mode 100644 __pycache__/VideoFile.cpython-38.pyc create mode 100644 antonio.ttf create mode 100644 main.py create mode 100644 requirements.txt create mode 100644 stream.sh create mode 100644 testsup.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..db62f6a --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +*.webm +*.mp4 +Dash/* +chunk/* +.venv +*.flv +*.jpg +*.mpd +*.m4s +*.pyd diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..73f69e0 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..8a932fd --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,26 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..cf36c21 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..3d44732 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/tryCanvas.iml b/.idea/tryCanvas.iml new file mode 100644 index 0000000..9655816 --- /dev/null +++ b/.idea/tryCanvas.iml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/StreamMerger.py b/StreamMerger.py new file mode 100644 index 0000000..2e9e80f --- /dev/null +++ b/StreamMerger.py @@ -0,0 +1,31 @@ +import time +from datetime import datetime +from threading import Thread + +from PIL import Image +from PIL import ImageDraw, ImageFont + +from VideoFile import VideoFile + + +class StreamMerger(Thread): + img = None + + def run(self) -> None: + video = VideoFile("yiv3.webm") + video2 = VideoFile("supernatural.webm") + video.open() + video2.open() + start_time = time.time() + while True: + img = Image.new('RGB', (1920, 1080), color='black') + + if video.frame is not None: + img.paste(video.frame) + if video2.frame is not None: + img.paste(video2.frame, (0, 600)) + fnt = ImageFont.truetype("antonio.ttf", 40) + d = ImageDraw.Draw(img) + d.text((0, 1000), str(int(time.time() - start_time)), font=fnt) + self.img = img + time.sleep(1.0 / 1000.0) diff --git a/VideoFile.py b/VideoFile.py new file mode 100644 index 0000000..eaa5804 --- /dev/null +++ b/VideoFile.py @@ -0,0 +1,43 @@ +import time +from threading import Thread + +import av +from PIL import Image + + +class VideoFile(Thread): + file: str = "" + frame: Image = None + running: bool = False + + def __init__(self, file: str): + self.file = file + super().__init__() + + def get_frame(self): + return self.frame + + def stop(self): + self.running = False + + def open(self): + self.running = True + self.start() + + def run(self) -> None: + container = av.open(self.file) + video = container.streams.video[0] + print(video.time_base) + + while self.running: + try: + for frame in container.decode(video): + + if self.running: + self.frame = frame.to_image() + else: + break + + time.sleep(1.0 / 60) + except: + self.running = False diff --git a/__pycache__/StreamMerger.cpython-38.pyc b/__pycache__/StreamMerger.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2b4bc6c8712a8930e1e18412ba61dcba3205a8a1 GIT binary patch literal 1102 zcmY*YJ8u&~5Z>3F@0?389W)TSToX$`L4g1flqeF3A_54VkdBLYZJ%=wXK$V0=qw>6 zl=%k~cA1u+Lb)vsDQOV}v+G1MYwheev!0!qZ|2@DFE_%?hh#FRRGcWfd52G!_8{9ib+!OSS zMn1>;DDn z1F#Ew19tTtgaUHT@C3t2;3PGk;u*rICi7E~DVd=ORdm2iK<;q&f=*bC2M$MvzTB70SsXtDSAFZE=gZ%V%H5v+8Bv5LSS(B!3wqAxL{Q||N zPhb?ZbC4ySL(`2;nUyjm(r}V~APAi@T@&0M?#GuMaTNt0bojeR+?5y zYMK^+(!8ggDidNDHZ-e5*456jnTyD^$3xw$R3cSu1Kx#~BH9H<%rB9=59*)C?S7ey z_Mq$+?Y(iQpU8YqmIKjIRa?pNMp7InReNzn)`w$F<)~Nz_sUEd!rsk~v`7;NxQSP+ zT*WRvZT;sAj-jKyI4+>#IM&TL&PzVZ3=ZP>Xq0608)>qY4~#I0E{Ij5dLWiySB6Co zGh!`aQ?|@4Gze*5*^enLdeVFmn(l4CwxnB1EzPzm)^p)~8*bHjcu(iKJu_{u0uUb5 L6_5b8NI?Gq^F9mY literal 0 HcmV?d00001 diff --git a/__pycache__/VideoFile.cpython-38.pyc b/__pycache__/VideoFile.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c14ed9cb6dd2fd1cdf159c39aaca7ee0f2923ec1 GIT binary patch literal 1485 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 literal 0 HcmV?d00001 diff --git a/main.py b/main.py new file mode 100644 index 0000000..d941ebe --- /dev/null +++ b/main.py @@ -0,0 +1,41 @@ +import time +from datetime import datetime + +import av +from PIL import Image +from av.frame import Fraction +from PIL import Image, ImageDraw, ImageFont + +from StreamMerger import StreamMerger +from VideoFile import VideoFile + +container = av.open('rtmp://localhost/live', mode='w', format='flv') +stream = container.add_stream('h264', framerate=60) # alibi frame rate +output_audio_stream = container.add_stream('aac', rate=44100) + +stream.width = 1920 +stream.height = 1080 +stream.pix_fmt = 'yuv420p' +# stream.bit_rate = 128000 +stream.time_base = Fraction(1, 60) + +st = StreamMerger() +st.start() +my_pts = 0 # [seconds] +frame_i = 0 +time_start = time.time() +while True: + if st.img is not None: + frame = av.VideoFrame.from_image(st.img) + framen = frame.reformat(format='yuv420p') + + ntime = time.time() - time_start + + frame.pts = ntime * 60 + frame.time_base = Fraction(1, 60) + # frame.key_frame = frame_i + frame_i += 1 + # print(dir(frame)) + for packet in stream.encode(framen): + container.mux(packet) + time.sleep(1.0 / 60.0) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..67321a8 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +av +pillow +aiortc \ No newline at end of file diff --git a/stream.sh b/stream.sh new file mode 100644 index 0000000..4b74a38 --- /dev/null +++ b/stream.sh @@ -0,0 +1,37 @@ +#!/bin/bash +#HLS, Dash and fallback code from zazu.berlin 2020, Version 20200424 + +VIDEO_IN=rtmp://localhost/live +VIDEO_OUT=master +HLS_TIME=4 +FPS=25 +GOP_SIZE=100 +PRESET_P=veryslow +V_SIZE_1=960x540 +V_SIZE_2=416x234 +V_SIZE_3=640x360 +V_SIZE_4=768x432 +V_SIZE_5=1280x720 +V_SIZE_6=1920x1080 + + +# DASH +ffmpeg -i $VIDEO_IN -y \ + -preset $PRESET_P -keyint_min $GOP_SIZE -g $GOP_SIZE -sc_threshold 0 -r $FPS -c:v libx264 -pix_fmt yuv420p \ + -map v:0 -s:0 $V_SIZE_1 -b:v:0 2M -maxrate:0 2.14M -bufsize:0 3.5M \ + -map v:0 -s:1 $V_SIZE_2 -b:v:1 145k -maxrate:1 155k -bufsize:1 220k \ + -map v:0 -s:2 $V_SIZE_3 -b:v:2 365k -maxrate:2 390k -bufsize:2 640k \ + -map v:0 -s:3 $V_SIZE_4 -b:v:3 730k -maxrate:3 781k -bufsize:3 1278k \ + -map v:0 -s:4 $V_SIZE_4 -b:v:4 1.1M -maxrate:4 1.17M -bufsize:4 2M \ + -map v:0 -s:5 $V_SIZE_5 -b:v:5 3M -maxrate:5 3.21M -bufsize:5 5.5M \ + -map v:0 -s:6 $V_SIZE_5 -b:v:6 4.5M -maxrate:6 4.8M -bufsize:6 8M \ + -map v:0 -s:7 $V_SIZE_6 -b:v:7 6M -maxrate:7 6.42M -bufsize:7 11M \ + -map v:0 -s:8 $V_SIZE_6 -b:v:8 7.8M -maxrate:8 8.3M -bufsize:8 14M \ + -init_seg_name init\$RepresentationID\$.\$ext\$ -media_seg_name chunk\$RepresentationID\$-\$Number%05d\$.\$ext\$ \ + -use_template 1 -use_timeline 1 \ + -seg_duration 4 -adaptation_sets "id=0,streams=v id=1,streams=a" \ + -f dash Dash/dash.mpd + +# Fallback video file +ffmpeg -i $VIDEO_IN -y -c:v libx264 -pix_fmt yuv420p -r $FPS -s $V_SIZE_1 -b:v 1.8M -c:a aac -b:a 128k -ac 1 -ar 44100 fallback-video-$V_SIZE_1.mp4 + diff --git a/testsup.py b/testsup.py new file mode 100644 index 0000000..b7d57ac --- /dev/null +++ b/testsup.py @@ -0,0 +1,46 @@ +import av +from av.filter import Graph + + +def main(): + input_container = av.open('supernatural.webm', mode='r') + input_container2 = av.open('yiv3.webm', mode='r') + input_video_stream = input_container.streams.video[0] + + output_container = av.open("out.mp4", "w") + output_audio_stream = output_container.add_stream('aac', rate=input_container2.streams.audio[0].base_rate) + + graph = Graph() + + in_src = graph.add_abuffer(template=input_container.streams.audio[0]) + in_src2 = graph.add_abuffer(template=input_container2.streams.audio[0]) + pad = graph.add("amix", "inputs=2:duration=longest") + print(dir(pad)) + in_src.link_to(pad, 0, 0) + in_src2.link_to(pad, 0, 1) + sink = graph.add('abuffersink') + pad.link_to(sink) + graph.configure() + + for frame in input_container.decode(audio=0): + in_src.push(frame) + + for frame in input_container2.decode(audio=0): + in_src2.push(frame) + while True: + try: + filtered_frame = pad.pull() + output_container.mux(output_audio_stream.encode(filtered_frame)) + except: + break + + for packet in output_audio_stream.encode(): + output_container.mux(packet) + + input_container.close() + input_container2.close() + output_container.close() + + +if __name__ == '__main__': + main()