import os import sys import time import datetime import shutil import pandas as pd import json import subprocess import requests from urllib.request import urlopen from bs4 import BeautifulSoup import warnings warnings.filterwarnings("ignore") def gen_web_m3u8_KBS() : try : url_0 = "https://onair.kbs.co.kr" html_0 = requests.get(url_0, verify = False) str_0 = html_0.text.split('\n') for i in str_0 : if 'var add_ch_code' in i : channel_list = i.split("'")[1].split(',') channerl_list += ['CP03', 'CP04', 'CP05', 'CP06', 'CP07', 'CP08', 'CP09', 'CP10', 'CP11', 'CP12'] except : channel_list = ['11','12','14','81', # 1TV, 2TV, WORLD, NEWS24 'N91','N92','N94','N93','N96', # DRAMA, JOY, LIFE, W, KIDS '21','22','23','24','25','26', 'I92', #1RADIO, 2RADIO, 3RADIo, 1FM, 2FM, hanminjok, workdradio 'nvod1','nvod2','nvod3','nvod4','nvod5', 'nvod6','nvod7','nvod8','nvod9','nvod10', 'wink11','I92','cctv01', # WINK11, DOKDO 'CP03', 'CP04', 'CP05', 'CP06', 'CP07', 'CP08', 'CP09', 'CP10', 'CP11', 'CP12'] # k-event url_1 = 'https://cfpwwwapi.kbs.co.kr/api/v1/landing/live/channel_code/' kbs_ch_info = [] for i in channel_list : html_1 = requests.get(url_1 + i, verify = False) str_1 = json.loads(html_1.text) for j in str_1['channel_item'] : #print(j['channel_id'], j['service_url']) kbs_ch_info.append({ 'media_type' : j['media_type'], 'channel_code' : j['channel_code'], 'channel_id' : j['channel_id'], 'service_url': j['service_url'], }) df = pd.DataFrame(kbs_ch_info) df['media_group'] = 9 df['media_type'] = df['media_type'].apply(lambda x : x.upper()) df['channel_id'] = 'KBS_' + df['channel_id'].apply(lambda x : x.upper()) def media_group(x) : if x == 'TV' : return 1 elif x == 'HTTPS' : return 2 elif x == 'BORA' : return 3 elif x == 'RADIO' : return 4 else : return 9 df['media_group'] = df['media_type'].apply(lambda x : media_group(x)) df = df[df['media_group'] < 7] df = df.sort_values(by = ['media_group', 'media_type', 'channel_code', 'channel_id']) web_m3u8_KBS = {} for i in df.index : web_m3u8_KBS[df.loc[i, 'channel_id']] = df.loc[i, 'service_url'] return web_m3u8_KBS web_url_list = gen_web_m3u8_KBS() web_url_list_1 = { 'MBC_GWANJ_TV' : 'http://media.kjmbc.co.kr:1935/live/stream/chunklist_w1919241667.m3u8', # 1920x1080 'MBC_YEOSU_TV' : 'https://5c3639aa99149.streamlock.net/live_TV/tv/playlist.m3u8', # 1920x1080 'MBC_CHNCN_TV' : 'https://stream.chmbc.co.kr/live/TV/playlist.m3u8', # 1920x1080 'MBC_MOKPO_TV' : 'https://vod.mpmbc.co.kr/a_live/25246741/ch001/chunklist_w1672872502.m3u8', # 1280x720 'SBS_TJB_TV' : 'http://1.245.74.5:1935/live/tv/playlist.m3u8', # 1920x1080 'SBS_KBC_TV' : 'http://119.200.131.11:1935/KBCTV/tv/playlist.m3u8', # 1920x1080 'SBS_JIBS_TV' : 'http://123.140.197.22/stream/1/play.m3u8', # 1280x720 'SBS_TBC_TV' : 'http://203.251.91.122:1935/on-air/tv/playlist.m3u8', # 854x480 #'SBS_TBC_TV' : 'http://221.157.125.239:1935/live/psike/playlist.m3u8', # 960x540 'TBS_TV' : 'https://cdntv.tbs.seoul.kr/tbs/_definst_/tbs_tv_web_720.smil/playlist.m3u8', 'NATV' : 'https://m.webcast.go.kr/live/_definst_/smil:natv_720p.smil/playlist.m3u8', 'K_TV' : 'https://hlive.ktv.go.kr/live/klive_h.stream/playlist.m3u8', 'ARIRANG_TV' : 'http://amdlive-ch01.ctnd.com.edgesuite.net/arirang_1ch/smil:arirang_1ch.smil/playlist.m3u8', 'GUGAK_TV' : 'https://mgugaklive.nowcdn.co.kr/gugakvideo/gugakvideo.stream/playlist.m3u8', 'TBN_kyungbuk' : 'https://5cc6beb04faf6.streamlock.net/kyungbuk/myStream/playlist.m3u8', } web_url_list.update(web_url_list_1) def check_freespace(wait_sec) : for i in range(wait_sec) : time.sleep(1) total, used, free = shutil.disk_usage(os.getcwd()) print(" >>> Countdown : ", str((wait_sec - i - 1) // 60), 'min', str((wait_sec - i - 1) % 60), 'sec', "[Free : " + '{0:,}'.format(int(free / (2**20))) + "MB] ", end = '\r', flush = True) def return_m3u8(web_url_name = 'KBS_1TV') : if '.m3u8' in web_url_list[web_url_name] : return web_url_list[web_url_name] elif 'KBS' in web_url_name : html = requests.get(web_url_list[web_url_name], verify = False) str_0 = html.text str_0 = str_0.split('\"') str_1 = [] for j in str_0 : if 'Expire' in j : str_1.append(j) if len(str_1) > 0 : if 'Bora' in web_url_list[web_url_name]: m3u8_url = str_1[-1].replace('\\', '') else : m3u8_url = str_1[0].replace('\\', '') return m3u8_url else : return None for _ in range(1) : # START DEFAULT VALUES num_ch_list = {} record_do_flag = False rec_minute_basic = 1 * 60 rec_minute_limit = 6 * 60 wait_minute_basic = 0 # START CHANNEL SELECTION for idx, i in enumerate(web_url_list) : print(' - ' + '{0:02d}'.format(idx) + ' : ', i) num_ch_list[idx] = i num_ch = input("\n$$ Select Chennel To Record (Default = 00) : ") if num_ch.isdigit() : num_ch = int(num_ch) else : num_ch = 0 if num_ch > len(num_ch_list) : num_ch = 0 rec_ch = num_ch_list[num_ch] print('-' * 100) print('▣ CHANNEL : ', rec_ch) print('▣ M3U8 : ', return_m3u8(rec_ch)) # START RECORD DURATION TIME rec_minute = input("\n$$ Input Duration Time To Record (in minute, Default = 60) : ") if rec_minute.isnumeric() : rec_minute = abs(int(rec_minute)) else : rec_minute = rec_minute_basic if rec_minute > rec_minute_limit : rec_minute = rec_minute_limit print('▣ REC_MINUTE : ', str(rec_minute)) # START RECORD RESERVATION TIME wait_minute = input("\n$$ Input Waiting Time To Record (in minute, Default = 0) : ") if wait_minute.isnumeric() : wait_minute = abs(int(wait_minute)) else : wait_minute = wait_minute_basic print('▣ WAIT_MINUTE : ', str(wait_minute)) # GENERATE FFMPEG COMMAND LINE url_stream_get = ' "' + return_m3u8(rec_ch) + '" ' url_stream_put = ' %Y%m%d_%H%M%S_' + rec_ch + '.mp4 ' rec_time_str = ' -t ' + '{0:02d}'.format(rec_minute//60) + ':' + '{0:02d}'.format(rec_minute%60) + ':00 ' option_str = ' -c copy -bsf:a aac_adtstoasc -f segment -segment_time ' + str(rec_minute * 60 * 2) + ' -strftime 1 ' cmd_line = 'ffmpeg -i ' + url_stream_get + rec_time_str + option_str + url_stream_put print('') print('▣ CMD : ', cmd_line) # GO/NO-GO STAGE if input("\n$$ Run To Record ? (yes or else) : ") == 'yes' : check_freespace(wait_minute * 60) subprocess.run(cmd_line, shell = True) print("\n$$ FFMPEG Recording Finished.") else : sys.exit("\n$$ Recording Program Stopped.")