반토막 인코더
최?신 nvidia 그래픽 가속 옵션 사용
파워쉘 (실행 준비)
- 튜링 아키텍쳐 이후 글카에서만 쓰는 것을 추천합니다. 및 추가 설명
- 윈도우용 FFmpeg 윈도우 버전 다운로드 방법 - 7r 채널
- 궁금한 점은 [파워쉘][FFmpeg][인코더] st.ps1 - 반토막인코더(리팩토링버전) - 7r 채널 여기서 질문
- 파워쉘 관리자권한실행 >> 아래 명령어 입력 (파워쉘 스크립트 사용권한 설명서)
Set-ExecutionPolicy RemoteSigned
박스
일단 안되면 이코드를 복사해서 메모장에 다른이름 저장 st.ps1으로 텍스트 인코딩은 ANSI로 설정해서 저장하세요.
param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 1)] [string]$SearchString = "*", [string]$SearchPath = $PWD, [string]$Extension = 'mkv', [switch]$Recurse ) function Get-EncodeOption($inputProcessNumber) { # 옵션_번호 { [HalfEncoder]$인코딩_옵션 = [HalfEncoder]::New(확장자, root_path, 인코딩파일뒤_프로세스명 입력, ffmpeg 인풋파일에 관한 인자, ffmpeg 아웃풋파일에 관한 인자) } 로 클래스 활용 새로운 인스턴스 만들면서 옵션 적용 switch ($inputProcessNumber) { 1 { [HalfEncoder]$encodingOption = [HalfEncoder]::New( $Extension, $SearchPath, '-#streamCopy', '', '-c copy' ) } 2 { [HalfEncoder]$encodingOption = [HalfEncoder]::New( '', $SearchPath, '-#audioOnly', '', '-vn -c:a copy' ) } 3 { [HalfEncoder]$encodingOption = [HalfEncoder]::New( $Extension, $SearchPath, '-#hevc', '-c:v h264_cuvid', '' ) } 4 { [HalfEncoder]$encodingOption = [HalfEncoder]::New( $Extension, $SearchPath, '-#vp9toHEVC', '-c:v vp9_cuvid', '' ) } 5 { [HalfEncoder]$encodingOption = [HalfEncoder]::New( $Extension, $SearchPath, '-#hevc_720p', '-c:v h264_cuvid -resize 1280x720', '' ) } 6 { [HalfEncoder]$encodingOption = [HalfEncoder]::New( $Extension, $SearchPath, '-#re_hevc_720p', '-c:v hevc_cuvid -resize 1280x720', '' ) } default { Clear-Host; $inputProcessNumber = $null } } return $encodingOption } # ========== 하단 수정 금지 ========= class HalfEncoder { [string]$newGPU = "-bf:v 5 -b_ref_mode:v middle -rc-lookahead 32 -spatial-aq 1 -temporal-aq 1 -aq-strength 12" [string]$nvidiaEnc = "-map 0:v:0 -c:v:0 hevc_nvenc -tag:v hvc1 -preset:v p7 -cq:v 26 -tune:v hq $newGPU -map 0:a:0 -c:a:0 copy" [string]$nvidia_memory = '-hwaccel cuda -hwaccel_output_format cuda' [string]$audio_ext = 'm4a' [string]$metadata = '-sn -dn -map_metadata -1 -map_chapters -1 -metadata creation_time=now -metadata encoded_by=7r -movflags faststart' [string]$preproperty = "-y -v 32 -hide_banner -ignore_unknown -protocol_whitelist `"file,http,https,tcp,tls,crypto`" -fflags discardcorrupt -correct_ts_overflow 0" [string]$HEext [string]$process_name [string]$full_dir [string]$ffmpeg_input_command [string]$ffmpeg_output_command HalfEncoder( [string]$gen_ext, [string]$gen_dir, [string]$gen_processName, [string]$gen_inputCommand, [string]$gen_outputCommand ) { $this.HEext = if ($gen_ext) { $gen_ext } else { $this.audio_ext } $this.process_name = $gen_processName $this.full_dir = Join-Path $gen_dir ($gen_processName.replace('-#', '')) $this.ffmpeg_input_command = if ($gen_outputCommand) { "{0} {1}" -f $this.preproperty, $gen_inputCommand } else { "{0} {1} {2}" -f $this.preproperty, $this.nvidia_memory, $gen_inputCommand } $this.ffmpeg_output_command = if ($gen_outputCommand) { "{0} {1}" -f $this.metadata, $gen_outputCommand } else { "{0} {1}" -f $this.metadata, $this.nvidiaEnc } } } function Remove-ListItem { param ( [array]$toRemoveList ) Write-Host "삭제될 파일 목록입니다. `r======= LIST =======" $toRemoveList.name $select_remove = Read-Host " `r==================== `r삭제하시겠습니까? [default: 아니오] `r==================== `r[1] 예 `r[2] 아니오 `rInput " if (!($select_remove -match '^[2]?$')) { Write-Host ">> 삭제합니다.`n" Remove-Item $toRemoveList } else { Write-Host ">> 삭제하지 않습니다.`n" } } function Invoke-VideoEncoding { $list = Get-ChildItem -Path $SearchPath -Recurse:$Recurse -File -Filter "*$($SearchString -replace '.\\', '')*" | Sort-Object -Property Length if (!$list) { Write-Host "`n파일이 존재하지 않습니다.`n" } else { while ($true) { Clear-Host Write-Host "반토막 인코더를 실행합니다. `rFile Search Keyword: $SearchString `r======= LIST =======" $list.name $select_process = Read-Host " `r==================== `rFFmpeg 인코더를 선택하시오. [default: 종료] `r==================== `r[q] 종료 `r[1] COPY `r[2] None-Video `r[3] HEVC `r[4] vp9 -> HEVC `r[5] h264/1080p -> HEVC/720p `r[6] HEVC/1080p -> 재인코딩/720p `rInput " if ($select_process -match '^[Qq]?$') { return } elseif ($select_process -match '^[1-6]$') { $half_enc_opt = Get-EncodeOption $select_process Write-Host break } } if (!(Test-Path $half_enc_opt.full_dir)) { New-Item $half_enc_opt.full_dir -Type Directory | Out-Null } $list | ForEach-Object { $start_time = get-date -Format "yyyy-MM-dd HH:mm:ss" [string]$cleanedFileName = $_.BaseName + $half_enc_opt.process_name + '.' + $half_enc_opt.HEext [string]$ffmpeg_args = @( $half_enc_opt.ffmpeg_input_command "-i `"${_}`"" $half_enc_opt.ffmpeg_output_command "`"$(Join-Path $half_enc_opt.full_dir $cleanedFileName)`"" ) Start-Process -FilePath ffmpeg.exe -ArgumentList $ffmpeg_args -NoNewWindow -Wait -Verbose Write-Host ">> 시작 시각: ${start_time} `r>> 종료 시각: $(get-date -Format "yyyy-MM-dd HH:mm:ss")`r`n" } Remove-ListItem $list } Write-Host "반토막 인코더가 종료됩니다...`n" } Invoke-VideoEncoding
박스 까서 내용물을 환경변수 설정한 폴더에 저장
각 옵션 번호별 활용법
- 스트림복사
- h264 비디오코덱으로 인코딩된 모든 동영상 > hevc 비디오코덱, 해상도 유지로 인코딩 옵션
- 모든 비디오 파일 음원 추출
- h264 비디오코덱으로 인코딩된 1080p 해상도 동영상 > hevc 비디오코덱, 720p 해상도로 인코딩
- hevc 비디오코덱으로 인코딩된 1008p 해상도 동영상 > hevc 비디오코덱, 720p 해상도로 인코딩
기본 설정 변경법
- 아래 처럼 써있는 라인 찾기param (
[Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 1)]
[string]$SearchString = "*",
[string]$SearchPath = $PWD,
[string]$Extension = 'mkv',
[switch]$Recurse
) - [string]$SearchString = 뒤에 "*"대신 ts나, 다른 확장자 입력 시 해당 확장자만 선택 가능
- "*"은 기본적으로 모든 파일명을 검색하는 정규식임
- st.ps1 실행시 뒤에 입력하지 않는 다면, 아래와 같이 따로 입력하는 명령어가 실행이 되니 참고 하시오.
(SearchString: 뒤에 원하는 검색어 입력하면됨)
- [string]$SearchPath = 뒤에 $PWD(현재 파워쉘이 실행되는 폴더경로를 말함) 대신에 "C:\1videos"같이 폴더 경로 설정 가능
(주의: "\"(역슬래쉬)로 각 폴더를 나누어야 함.)- 실녹기의 기본 폴더 설정임.
- 입력한 폴더에 [hevc인코딩, 스트림 복사, 오디오추출] 이렇게 세 개의 폴더가 생성됨
- [string]$Extension = 뒤에 'mkv'대신 원하는 비디오/오디오 컨테이너 확장자 입력,(mkv,mp4 추천)
- [switch]$Recurse는 st.ps1 [중간에_입력한_여러_명령어들] 뒤에 -Recurse 라고 입력해서 실행하면 하위 폴더 내 모든 파일들일 검색해서 실행함.
- 개인적으로는 따로 입력하지 않고 그냥 그대로 쓰는 것을 추천
- [switch] 변수는 기본적으로 입력하지 않으면 $false로 작동함.
- -Recurse 옵션이 하위 폴더 내 파일 모두 검색 옵션이기 때문에 꼭 필요하지 않는 이상 쓰지 않는 것을 추천합니다.
- param () 안에 $로 시작하는 각 변수는 파워쉘 명령에서 따로 설정하지 않으면 생기는 default 값임.
- 파워쉘에서 입력할 때, 해당 인자가 입력되면, 입력한 대로 사용됨.
- st -dir 이렇식으로 변수명을 입력하면, 순서 상관 없이 알아서 지정됨.
- 관련 내용은 아래 활용법에서 정리해드림.
- 그래픽 가속 인코딩이고, nvdia 그래픽 카드만 가능합니다.
- 그 중에서 1000번대 이전 구형 그래픽 카드는 [string]$newGPU = "블라블라" 써진 코드 앞에 '#' 을 붙여주면 알아서 오류가 해결됩니다.
파워쉘에서 사용방법
순서 상관 없이 인자 뒤에 값으로 설정
st -SearchString [파일명에서_공통부분입력] -SearchPath [인코딩_후_저장할_폴더지정] -Extension [인코딩_후_파일_확장자_설정] -Recurse(입력할지말지선택)
인자 없이, 순서로 인자값 설정
st [파일명에서_공통부분입력] [인코딩_후_저장할_폴더지정] [인코딩_후_파일_확장자_설정] -Recurse(입력할지말지선택)
각 인자 입력 방식으로 활용법 정리
아래의 예시는 구버전의 목록이지만 응용할 수 있는 힌트로 보시면 됩니다.
각 예시 사진을 보면서 확인해보세요.
1. 아무것도 입력 없이 명령어만 입력
st
2. 각 파일명에서 공통되는 텍스트 입력
(주로 스트 아이디 입력으로 해당 파일 긁어모음)
st [공통되는_파일명]
3. 모든파일들을 "원하는폴더"에 저장(공백으로 구분)
st * [원하는폴더]
4. '공통되는파일명' '원하는폴더' 모두 지정(공백으로 구분)
st [공통되는파일명] [원하는폴더]