기술 · 실용 가이드
반복 클립을 합치지 않고 Shotcut의 저장된 재생목록을 CSV로 만들기
반복 하위 클립, 저장된 표시 이름과 원래 트림 값을 오프라인 표에 보존하세요. 재생목록 보고서는 타임라인 의존 파일 목록이나 삭제 목록이 아닙니다.

Shotcut 재생목록에서 필요한 정보는 고유한 미디어 파일 이름 목록만으로는 사라질 수 있습니다. 같은 파일을 쓰는 두 항목도 트림 범위가 다를 수 있습니다. 저장된 재생목록 보고서는 이를 한 리소스로 합치지 않고 항목별 순서와 저장된 표시 이름을 남겨야 합니다.
Shotcut은 이미 재생목록 빈에서 동영상을 내보내며 현재 일괄 이름 설정은 원본 이름도 쓸 수 있습니다. 이 가이드는 자신의 저장된 메인 재생목록을 제한된 형식의 오프라인 CSV로 만드는 방법을 추가합니다. 지원되는 MLT 복사본을 읽을 뿐 프로젝트를 바꾸거나 미디어를 열지 않습니다. 동영상 내보내기나 삭제 가능한 파일 판정은 하지 않습니다.
프로젝트를 저장하고 목록 종류 구별하기
현재 프로젝트를 저장하고 닫은 뒤 보고서용 별도 MLT 복사본을 project.mlt로 보관하세요. 자신의 UTF-8 일반 XML이며 최상위 main_bin 재생목록 또는 이전 main bin 표기가 정확히 하나이고 직접 entry가 최상위 producer나 chain을 참조해야 합니다. 네임스페이스, 중첩·복합 항목, 빈 구간 항목과 선언이 있는 XML은 범위 밖이며 출력 생성 전에 중단합니다.
저장된 메인 재생목록의 모든 항목을 읽습니다. 실행 중인 화면의 선택 빈, 검색 필터나 표시 순서는 읽지 않습니다. 현재 소스에서 shotcut:bins는 저장된 빈 문자열, shotcut:caption은 표시 이름입니다. 속성이 없으면 셀은 비어 있습니다. 파일 이름에 따른 자동 표시 이름, 스마트 빈 소속이나 화면의 대체 표시는 재현하지 않습니다.
동영상 파일이 필요하면 Shotcut 기본 Current Playlist Bin 또는 Each Playlist Bin Item 내보내기를 사용하세요. 고유한 리소스 목록은 기존 MLT Analyzer가 다운로드를 제공합니다. 이 보고서는 저장된 항목 순서와 반복을 남기는 별도 출력입니다. 이동한 프로젝트를 복구하거나 경로를 변경하지 않습니다.
지원 범위 안에서 CSV 변환 실행하기
Python 3가 있는 Linux Bash 터미널에서 project.mlt 복사본 폴더로 이동하세요. 다음 명령을 한 줄로 복사하고 곧은 따옴표와 역슬래시를 유지합니다. 새 출력 이름을 고르세요. 기존 playlist.csv는 덮어쓰지 않고 거부됩니다. 이 정확한 명령은 Linux Bash에서만 실행했으며 Windows와 macOS에서는 검사하지 않았습니다.
XML 파서는 메인 재생목록 참조를 producer나 chain에 연결하고 바로 아래의 선택된 속성만 읽습니다. 필터 자체의 resource를 클립의 리소스로 간주하지 않습니다. 최상위 ID 중복, 누락 참조, 선택 속성 중복이나 지원되지 않는 entry 구조는 CSV 생성 전에 멈춥니다.
python3 -c 'exec('"'"'import csv, sys, xml.etree.ElementTree as E\nfrom pathlib import Path\nsrc, dst = map(Path, sys.argv[1:])\nraw = src.read_bytes()\ntext = raw.decode("utf-8-sig")\nif "<!DOCTYPE" in text.upper() or "<!ENTITY" in text.upper():\n raise ValueError("Own plain XML only; declarations unsupported")\nroot = E.fromstring(text)\nif root.tag != "mlt":\n raise ValueError("Expected unnamespaced mlt root")\nbins = [x for x in root if x.tag == "playlist" and x.get("id") in ("main_bin", "main bin")]\nif len(bins) != 1:\n raise ValueError("Need exactly one saved main playlist")\nobjects = {}\nfor x in root:\n if x.get("id"):\n if x.get("id") in objects:\n raise ValueError("Duplicate top-level ID")\n objects[x.get("id")] = x\nkeys = ["shotcut:caption", "shotcut:bins", "mlt_service", "resource", "shotcut:resource", "warp_resource", "shotcut:comment"]\nrows = []\nfor entry in bins[0]:\n if entry.tag == "property":\n continue\n if entry.tag != "entry" or len(entry):\n raise ValueError("Only direct referenced entries supported")\n pid = entry.get("producer", "")\n obj = objects.get(pid)\n if obj is None or obj.tag not in ("producer", "chain"):\n raise ValueError("Missing or composite producer reference")\n values = {}\n for prop in obj.findall("property"):\n name = prop.get("name")\n if name in keys:\n if name in values or len(prop):\n raise ValueError("Duplicate or nested selected property")\n values[name] = prop.get("value", prop.text or "")\n rows.append([str(len(rows)+1), pid, values.get(keys[0], ""), values.get(keys[1], ""), entry.get("in", ""), entry.get("out", "")] + [values.get(k, "") for k in keys[2:]])\nheader = ["ordinal", "producer_id", "caption", "bin_raw", "in_raw", "out_raw", "service", "resource_raw", "proxy_original_raw", "warp_resource_raw", "comment"]\nwith dst.open("x", encoding="utf-8-sig", newline="") as f:\n w = csv.writer(f)\n w.writerow(header)\n w.writerows(rows)\nwith dst.open(encoding="utf-8-sig", newline="") as f:\n if list(csv.reader(f)) != [header] + rows:\n raise ValueError("Readback mismatch; discard partial CSV")\nprint(str(len(rows)) + " saved playlist entries checked; not a timeline or deletion list")\n'"'"')' "project.mlt" "playlist.csv"
열한 열을 문자열로 해석하기
열은 ordinal, producer_id, caption, bin_raw, in_raw, out_raw, service, resource_raw, proxy_original_raw, warp_resource_raw, comment입니다. ordinal은 저장된 항목 순서대로 1부터 시작합니다. 표시 이름, 빈과 설명은 저장된 속성이며 파일 이름에서 추정한 정보가 아닙니다. 빈 셀은 이 방법으로 값이 기록되지 않았다는 뜻일 뿐 미사용이나 손상을 증명하지 않습니다.
in_raw와 out_raw는 앞자리 0을 포함한 파싱된 속성 문자열을 그대로 남기며 누락 경계는 비웁니다. 길이를 계산하거나 암묵적 경계를 해석하거나 재생 범위를 검사하지 않습니다. MLT 값은 표현 형식과 프로젝트 맥락에 따라 달라지므로 초로 가정해 빼지 마세요. XML 이스케이프는 파싱 과정에서 풀립니다. XML 표기를 바이트 그대로 재현하는 표가 아닙니다.
리소스 세 필드는 분리합니다. resource_raw는 resource, proxy_original_raw는 shotcut:resource, warp_resource_raw는 warp_resource를 기록합니다. timewarp 리소스에는 속도 접두사가 포함될 수 있으며 프록시 관련 속성도 다를 수 있습니다. 경로 확장, 절대 경로화, 존재 확인이나 올바른 원본 선택은 하지 않습니다. 중첩 프로젝트, 필터, 마스크, LUT나 이미지 시퀀스 의존 관계도 탐색하지 않습니다.
사용 전에 행 대조하기
명령은 성공 표시 전에 CSV를 다시 읽어 헤더와 모든 필드를 파싱된 행과 비교합니다. 항목 수를 저장된 메인 재생목록과 비교하고 같은 소스의 서로 다른 트림 두 항목과 알려진 사용자 표시 이름을 확인하세요. 원래 MLT와 CSV 원본을 보관하며 필터나 인계 메모는 작업 복사본에서만 추가합니다. 크레딧에 필요한 제작자와 이용 허락은 따로 확인하세요. 파일 이름과 표시 이름으로 알 수 없습니다.
LibreOffice Calc에서 UTF-8, 쉼표 구분과 곧은 큰따옴표 문자열 구분으로 가져옵니다. 열한 열 모두 텍스트로 설정하고 구분자 병합, 공백 제거와 수식 평가를 끄세요. 창이 숨겨지면 필터 설정 편집을 켭니다. 확인 복사본에서 시간 문자열을 날짜로, 저장된 설명을 수식으로 취급하지 않도록 합니다. Calc 화면은 실행하지 않았습니다.
이 정확한 명령으로 21개 합성 사례를 실행했습니다. 정상 여섯 사례에는 반복 순서, Unicode와 XML 이스케이프, 속도·프록시 원래 필드, 이전 ID, 누락 경계, 비어 있는 빈, 타임라인·필터 리소스와의 분리가 포함됐습니다. 잘못된 열다섯 사례는 출력 생성 전에 멈췄습니다. 정상 출력 덮어쓰기 여섯 번도 거부하고 입력과 기존 출력 바이트가 불변임을 확인했습니다. 실제 Shotcut 프로젝트, 재생, GUI, Windows나 macOS 실행은 검사하지 않았습니다. 쓰기나 다시 읽기가 실패하면 부분 CSV를 버리고 새 이름으로 다시 시도하세요. 이 표를 미디어 삭제 허가로 쓰지 마세요.
