-
Notifications
You must be signed in to change notification settings - Fork 62
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Channel count as an input feature #84
Channel count as an input feature #84
Conversation
We can also follow the |
streamer/input_configuration.py
Outdated
@@ -146,6 +146,9 @@ class Input(configuration.Base): | |||
Otherwise, it will default to 'und' (undetermined). | |||
""" | |||
|
|||
channels = configuration.Field(int).cast() | |||
"""The number of audio channels to encode.""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's more like "The number of channels in an audio input", right? It's less about encoding, and more about the structure of the input. Do I understand that right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, i feel a bit confused because of this too.
This is actually an output feature, the number of channels to encode in the final output file. sticking it with the each input(instead of the pipeline config) will allow us to give different channel counts for each input in a multi-period list.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another less confusing approach could be, to deal with it like resolutions, we may specify the channel counts we want as an output to be encoded with, and it's a list of channel counts rather than a single channel count and each input will be encoded with different channel counts up till its own channel count just like video resolutions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would make sense to me. I like having it in the input, though, with auto-detection, just like resolution and frame rate for video inputs. If auto-detect fails, or if the input is coming from a pipe, rather than a file, we would need to be able to specify it in the input config.
So let's keep what you have (but fix the comment here on the field meaning), and then let's add a list of output channel counts in the pipeline config, just like we do for resolutions.
…r is raised" This reverts commit 9bd8c7e.
streamer/configuration.py
Outdated
@@ -561,5 +561,5 @@ def validate(cls, key): | |||
|
|||
if key not in cls.map_class.keys(): | |||
raise ValueError( | |||
'{} is not a valid {}'.format(key, cls.map_class.__name__)) | |||
'{} is not a valid {}, {}'.format(key, cls.map_class.__name__, cls.name())) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From what I can tell re-reading the source, this now repeats cls.map_class.__name__
, which is also printed by name() above:
"foo is not a valid VideoResolution, VideoResolution name (one of 720p, 1080p, ...)"
Should we drop cls.map_class.__name__
in favor of cls.name()?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You read that write.
Yes i think we should drop it in favor of cls.name()
.
streamer/pipeline_configuration.py
Outdated
"""The number of audio channels to encode.""" | ||
channel_layouts = configuration.Field( | ||
List[bitrate_configuration.AudioChannelLayoutName], | ||
required=True).cast() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't agree with making this a required field. I think we should have a default value instead. Perhaps ['surround', 'stereo']
. Not sure. What are your thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I fear that someone might provide a generic bitrate config that doesn't have stereo
in it.
My thoughts is that we can default to a list that contains only the lowest channel_layout
. So we read the channel_layouts
using the BitrateConfig
class and then provide this list as a default [AudioChannelLayout.sorted_values()[0].get_key()]
, now it will pick stereo
by default, or, when a generic user provided bitrate config is there, it will pick the lowest of what ever the user has.
We can do the same for resolutions
field as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Too bad this is not gonna work :(,
Because channel_layouts
and resolutions
are class variables and are initialized at indexing time, so even before the bitrate config is provided.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you agree to the proposed idea above, we can monkey-patch the default
of these fields in the __init__
of the PipelineConfig
.
like this.
self.__class__.resolutions.default=[ # type: ignore
bitrate_configuration.VideoResolution.sorted_values()[0].get_key()]
self.__class__.channel_layouts.default=[ # type: ignore
bitrate_configuration.AudioChannelLayout.sorted_values()[0].get_key()]
we need the # type: ignore
now because since we did the cast()
for these class attributes, mypy will think they are actual [RuntimeMap]
while they are actually Field
instances.
tests/tests.js
Outdated
'audio_codecs': ['aac', 'opus'], | ||
}; | ||
await startStreamer(inputConfigDict, pipelineConfigDict); | ||
await player.load(manifestUrl); | ||
|
||
const trackList = player.getVariantTracks(); | ||
const audioCodecList = trackList.map(track => track.audioCodec); | ||
let codecList = await getAudioAndVideoCodecs(manifestUrl) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style nit: Add a semicolon at the end of this statement.
tests/tests.js
Outdated
@@ -726,17 +740,17 @@ function codecTests(manifestUrl, format) { | |||
const pipelineConfigDict = { | |||
'streaming_mode': 'vod', | |||
'resolutions': [], | |||
'channel_layouts': ['stereo'], | |||
'audio_codecs': ['aac', 'opus'], | |||
}; | |||
await startStreamer(inputConfigDict, pipelineConfigDict); | |||
await player.load(manifestUrl); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to call player.load() if you're using getAudioAndVideoCodecs(), which will do that internally.
streamer/pipeline_configuration.py
Outdated
@@ -307,6 +305,10 @@ class PipelineConfig(configuration.Base): | |||
|
|||
|
|||
def __init__(self, *args) -> None: | |||
self.__class__.resolutions.default=[ # type: ignore |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since resolution and channel layout have a behavior of "use every option that doesn't upscale/upmix", perhaps the best default would be the entire list. Can you please try that and let me know how it goes? Also, please update the docstrings for those fields to say that they default to all defined values from the bitrate config.
Looks like there are a couple of conflicts with the Windows PR. Can you rebase/merge and fix those up please? |
|
||
# The features that will be used to generate the output filename. | ||
self._features = { | ||
'language': input.language, | ||
'channels': str(self.channels), | ||
'channels': str(self.layout.max_channels), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you like having this to be 'channel_layout': self.layout.get_key()
instead.
@joeyparrish
…Cannot assign to a type'
… on the wrong platform
This PR removes the
channels
field from the pipeline configuration and replaces it withchannel_layouts
, a list of channel layouts to encode.It also adds
channel_layout
field forInput
class.