-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Receive-Media.ps1
162 lines (133 loc) · 5.17 KB
/
Receive-Media.ps1
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
function Receive-Media
{
<#
.SYNOPSIS
Receives Media from an Input
.DESCRIPTION
Receives media from inputs.
.NOTES
Stopping a script that is receiving media with CTRL+C may prevent certain filetypes from being finalized.
For best results, use a filetype designed for streaming, such as .wav for audio or .mpg for video.
Alternatively, if you run Receive-Media -AsJob, stopping the job will normally allow FFMpeg to finalize.
.EXAMPLE
Receive-Media -DirectShow -VideoDevice "OBS Virtual Camera" -OutputPath .\Desktop.mpg
.EXAMPLE
Receive-Media -DirectShow -VideoDevice "OBS Virtual Camera" -OutputPath .\Desktop.mkv -AsJob
.LINK
Send-Media
#>
param(
# The input device type.
[Parameter(ParameterSetName='InputDevice',ValueFromPipelineByPropertyName)]
[string]
$InputType,
# The input device identifier. This will be specific to a given input type.
[Parameter(ParameterSetName='InputDevice',ValueFromPipelineByPropertyName)]
[string]
$InputDevice,
# If provided, will use a specific pixel format for video and image output. This maps to the -pix_fmt parameter in ffmpeg.
[Parameter(ValueFromPipelineByPropertyName)]
[Alias('Pix_Fmt')]
[string]
$PixelFormat,
# The frame rate of the outputted video
[Parameter(ValueFromPipelineByPropertyName)]
[string]
$FrameRate,
# The number of frames to output.
[Parameter(ValueFromPipelineByPropertyName)]
[string]
$FrameCount,
# The duration to record. If not provided, will record indefinitely.
[Parameter(ValueFromPipelineByPropertyName)]
[Timespan]
$Duration,
# A list of additional arguments to FFMpeg.
[Alias('Arguments','Argument','ArgumentList','FFArgs')]
[Parameter(ValueFromRemainingArguments)]
[string[]]
$FFMpegArgument,
# If set, will save output to a file
[Parameter(ValueFromPipelineByPropertyName)]
[string]
$OutputPath,
# If set, will run as a background job.
[switch]
$AsJob,
# If set, will limit the number of background jobs to a throttle limit.
# By default 5.
# Throttling is only available if running on PowerShell Core.
[int]
$ThrottleLimit,
# The path to FFMpeg.exe. By default, checks in the path.
[string]
$FFMpegPath
)
dynamicParam {
$myCmd = $MyInvocation.MyCommand
Get-RoughDraftExtension -CommandName $myCmd -DynamicParameter
}
process {
if ($AsJob) { # If -AsJob was passed,
return & $StartRoughDraftJob # start a background job.
}
$in = @{} + $PSBoundParameters
:receivingMedia do {
#region Handle Extensions
$extensionArguments = @()
Get-RoughDraftExtension -CommandName $myCmd -CanRun -ExtensionParameter $in |
. Get-RoughDraftExtension -Run |
. { process {
$inObj = $_
if ($inObj.ExtensionOutput) {
Write-Verbose "Adding Arguments from Extension '$extensionCommand'"
Write-Verbose "$($inObj.extensionOutput)"
$extensionArguments += $inObj.extensionOutput
}
if ($inObj.Done) {
break receivingMedia
}
} }
#endregion Handle Extensions
$allArguments = @()
if ($InputType -and $InputDevice) {
$allArguments += '-f', $InputType, '-i', $InputDevice
}
if ($extensionArguments) {
$allArguments += $extensionArguments
}
if ($PixelFormat) {
$allArguments += '-pix_fmt', $PixelFormat
}
if ($FrameRate) { # If -FrameRate was passed
$allArguments += "-r" # use '-r' to set it.
$allArguments += "$FrameRate"
}
if ($FrameCount) {
$allArguments += "-frames" # use '-r' to set it.
$allArguments += "$FrameCount"
} elseif ($Duration.TotalMilliseconds -ge 0) {
$allArguments += '-t' # then use '-to' to set the end time.
$allArguments += "$Duration"
}
$allArguments += $FFMpegArgument
if ($OutputPath) {
$allArguments += $OutputPath, '-y'
}
$ProgId = Get-Random
Write-Verbose "FFMpeg Arguments: $allArguments"
Use-FFMpeg -FFMpegArgument $allArguments -FFMpegPath $FFMpegPath |
ForEach-Object {
$outLine = $_
Write-Verbose $outLine
$progress = $outLine | & ${?<FFMpeg_Progress>} -Extract
if ($progress -and
$progress.Time.Totalmilliseconds
) {
Write-Progress "Receiving Media" "$($progress.Time)" -Id $ProgId
}
}
Write-Progress "Receiving Media" " " -Id $ProgId -Completed
} while ($false)
}
}