如何确定音轨是否为Dolby Pro Logic II混音

时间:2017-04-13 09:32:39

标签: audio aac audio-processing handbrake dolby

我试图找出是否有办法确定AAC编码的音轨是否采用杜比定向逻辑II数据进行编码。有没有办法检查文件,以便您可以看到此信息?例如,我在Handbrake中编码了一个媒体文件(截断为音频选项)#Exclude some path RewriteCond %{REQUEST_URI} ^/path-one/some-link-1$ [OR] RewriteCond %{REQUEST_URI} ^/path-one/some-link-2$ [OR] RewriteCond %{REQUEST_URI} ^/path-one/some-link-3$ [OR] RewriteCond %{REQUEST_URI} ^/path-one/some-link-4$ [OR] RewriteCond %{REQUEST_URI} ^/path-one/some-link-5$ RewriteCond %{HTTP_HOST} ^subdomain1\.domain\.com$ RewriteRule .* - [L] # Redirect if RewriteCond %{HTTP_HOST} ^subdomain1\.domain\.com$ [NC] RewriteRule ^(.*) http://subdomain2.domain.com%{REQUEST_URI} [R=301,L] ,这是java.lang.NullPointerException: null at org.springframework.boot.autoconfigure.EnableAutoConfigurationImportSelector.isEnabled(EnableAutoConfigurationImportSelector.java:42) ~[spring-boot-autoconfigure-1.5.2.RELEASE.jar:1.5.2.RELEASE] at org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.selectImports(AutoConfigurationImportSelector.java:88) ~[spring-boot-autoconfigure-1.5.2.RELEASE.jar:1.5.2.RELEASE] at org.springframework.context.annotation.ConfigurationClassParser.processImport(ConfigurationClassParser.java:388) ~[spring-context-3.2.6.RELEASE.jar:3.2.6.RELEASE] at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:207) ~[spring-context-3.2.6.RELEASE.jar:3.2.6.RELEASE] at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:165) ~[spring-context-3.2.6.RELEASE.jar:3.2.6.RELEASE] at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:140) ~[spring-context-3.2.6.RELEASE.jar:3.2.6.RELEASE] at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:284) ~[spring-context-3.2.6.RELEASE.jar:3.2.6.RELEASE] at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:225) ~[spring-context-3.2.6.RELEASE.jar:3.2.6.RELEASE] at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:630) ~[spring-context-3.2.6.RELEASE.jar:3.2.6.RELEASE] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:461) ~[spring-context-3.2.6.RELEASE.jar:3.2.6.RELEASE] at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:370) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:314) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1162) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1151) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE] at fi.ma.vegshopping.app.VegShoppingApplication.main(VegShoppingApplication.java:16) [classes/:na] 2017-04-13 10:20:35.199 INFO 10788 --- [ main] ationConfigEmbeddedWebApplicationContext : Closing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@797badd3: startup date [Thu Apr 13 10:20:35 BST 2017]; root of context hierarchy 2017-04-13 10:20:35.200 WARN 10788 --- [ main] ationConfigEmbeddedWebApplicationContext : Exception thrown from ApplicationListener handling ContextClosedEvent java.lang.IllegalStateException: ApplicationEventMulticaster not initialized - call 'refresh' before multicasting events via the context: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@797badd3: startup date [Thu Apr 13 10:20:35 BST 2017]; root of context hierarchy at org.springframework.context.support.AbstractApplicationContext.getApplicationEventMulticaster(AbstractApplicationContext.java:347) [spring-context-3.2.6.RELEASE.jar:3.2.6.RELEASE] at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:334) [spring-context-3.2.6.RELEASE.jar:3.2.6.RELEASE] at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1049) [spring-context-3.2.6.RELEASE.jar:3.2.6.RELEASE] at org.springframework.context.support.AbstractApplicationContext.close(AbstractApplicationContext.java:1010) [spring-context-3.2.6.RELEASE.jar:3.2.6.RELEASE] at org.springframework.boot.SpringApplication.handleRunFailure(SpringApplication.java:794) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:325) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1162) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1151) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE] at fi.ma.vegshopping.app.VegShoppingApplication.main(VegShoppingApplication.java:16) [classes/:na] 2017-04-13 10:20:35.200 WARN 10788 --- [ main] ationConfigEmbeddedWebApplicationContext : Exception thrown from LifecycleProcessor on context close java.lang.IllegalStateException: LifecycleProcessor not initialized - call 'refresh' before invoking lifecycle methods via the context: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@797badd3: startup date [Thu Apr 13 10:20:35 BST 2017]; root of context hierarchy at org.springframework.context.support.AbstractApplicationContext.getLifecycleProcessor(AbstractApplicationContext.java:360) [spring-context-3.2.6.RELEASE.jar:3.2.6.RELEASE] at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1057) [spring-context-3.2.6.RELEASE.jar:3.2.6.RELEASE] at org.springframework.context.support.AbstractApplicationContext.close(AbstractApplicationContext.java:1010) [spring-context-3.2.6.RELEASE.jar:3.2.6.RELEASE] at org.springframework.boot.SpringApplication.handleRunFailure(SpringApplication.java:794) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:325) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1162) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1151) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE] at fi.ma.vegshopping.app.VegShoppingApplication.main(VegShoppingApplication.java:16) [classes/:na] 显示的音轨输出:

-E av_aac -B 320 --mixdown dpl2

但是我不知道这个输出中是否有任何东西表明它是用DPL2数据编码的。

2 个答案:

答案 0 :(得分:5)

TL:博士;它可能是可能的;如果你是一名程序员,可能会更容易。

由于编码的信息只是一个立体声模拟对,因此无法保证在其中检测Dolby Pro Logic II(DPL2)信号,除非您专门存储自己的元数据说"这是一个DPL2文件。 "但你可以做出很好的猜测。

所有旧的模拟杜比环绕声格式,包括DPL2,通过反转环绕声或环绕声的相位,然后将它们混合到原始的左右声道中,将环绕声信息存储在两个声道中。杜比环绕型解码器(包括DPL2)尝试通过反转两个通道之一的相位来恢复此信息,然后查找这些信号对中的相似性。这可以通过杜比环绕声来完成,或者这些相似性被人为地偏向左侧或右侧,或左侧或右侧环绕,如DPL2中那样。

因此,技巧是检测重要数据是否存储在环绕声道中。我将为您绘制一个可行的方法,并且我会尝试在不编写代码的情况下表达它,但是您可以根据自己的喜好来实现和完善它。

  1. 将节目内容的前N秒左右裁剪为立体声文件,其中N介于1到30之间。调用此文件输入。
  2. 将输入立体声声道混合到新的单声道文件,每声道-3dB。将此文件称为中心。
  3. 将Input的左右声道拆分为单独的文件。称这些左和右。
  4. 反转正确的频道。将此文件称为RightInvert。
  5. 将Left和RightInvert通道混合到一个新的单声道文件,每通道-3dB。将此文件称为Surround。
  6. 确定环绕声文件的RMS和峰值dB。
  7. 如果环绕声文件的RMS或峰值DB低于"容差",则停止;原始文件是单声道或中心声像,因此不包含环绕声信息。您必须尝试使用​​多个DPL2和非DPL2源来查看这些容差是什么,但在十几个文件之后,数字应该变得清晰。我估计大约-30 dB左右。
  8. 将中心文件反转为新文件。将此文件称为CenterInvert。
  9. 将CenterInvert文件以0 dB的比例混合到环绕文件中(CenterInvert和Surround都应为单声道)。将此新文件称为SurroundInvert。
  10. 确定SurroundInvert文件的RMS和峰值dB。
  11. 如果SurroundInvert的RMS和/或峰值dB低于"公差,"停;您的原始来源包含平移的左前或右前方信息,而不是环绕声信息。您必须尝试使用​​多个DPL2和非DPL2源来查看这些容差是什么,但是在十几个文件之后,数字应该变得清晰 - 我估计大约-35 dB左右。
  12. 如果您已经走到这一步,您的原始输入可能包含环绕声信息,因此可能是杜比环绕声编码系列的成员。
  13. 我已经编写了这个算法,您可以使用sox中的特定命令执行这些步骤。如果你想变得更漂亮,而不是在sox中执行RMS /峰值步骤,你可以运行ebur128程序并检查LUFS中的容差与容差。如果您想要更加漂亮,在创建环绕声和中心文件后,您可以滤除高于7kHz的所有频率并对其进行去加重,就像真正的DPL2解码器一样。

    为了保持这个算法简单,我已经完全在幅度域中绘制了它。如果您知道如何计算FFT分档的幅度和角度并使用30到100 ms的窗口,那么SurroundLevel文件的计算可能在频域中更准确地完成。但是上面的这个便宜版本应该让你开始。

    最后一个警告。 AAC是一种现代心理声学编解码器,这意味着它喜欢用立体相位和成像来玩游戏以实现其压缩。因此,我认为仅将DPL2封装到AAC流中的行为可能会影响DPL2中存在的一些成像。坦率地说,DPL2和AAC都不属于这个管道中的任何地方。如果您必须存储最初使用DPL2编码的模拟流,请使用WAV或FLAC等无损格式,而不是AAC。

    在撰写本文时,杜比定向逻辑(I)背后的操作概念是here。这些基本概念仍适用于DPL2; DPL2的操作概念是here

答案 1 :(得分:2)

如果文件有多个频道,您可以肯定地假设它们用于环绕目的,尽管它们可能只是多个音轨。 在这种情况下,由于它“认为”最佳,因此它与播放系统有关。 (如果文件标题没有说明要做什么)

但你的文件是立体声。如果您想知道它是否是虚拟环绕声文件,那么您可以在标题中查找编码器字段以查看使用了哪个编码器。 这可能有所帮助,虽然不多。大多数编码器字段是空的,第二个是编码器不必与混合环绕数据的重新编码器相同。 即重新编码器将首先创建原始PCM数据,然后将其提供给某个编码器以生成压缩文件。 (AAC或其他) 此外,有许多应用程序和版本各不相同,因此编码器字段可能会有所不同,因此跟踪所有这些将是令人讨厌的工作。

但是,您可以通过检查数据,以超过60%的确定性来推断某些事物是否为虚拟环绕声。 这将是先进的DSP,为了提高速度,甚至可能涉及机器学习。 你必须要弄清楚立体声信号是否包含HRTF的某些特征(头部相关传递函数)。 这可以通过检查时域中出现的相同声音与频域中的谐波特征(特征频率变化)之间的强度差异和延迟特征来实现。 你必须要做到这两点,因为一个没有另一个可能只是告诉你某些东西是非常好的立体声录音,而不是虚拟环绕声。 我不知道是否已经在某处映射了HRTF特定功能,或者您需要自己完成。

这是一个非常复杂的解决方案,需要花费大量时间才能正确完成。它的性能也会有问题。

使用此方法,您还可以将立体声混音分解为近乎原始的环绕声道。 但是对于立体声到环绕声转换,使用其他方法,它们听起来很好。

如果您决定执行这样的检测,如果没有映射HRTF功能,则需要花费半年或更长时间的努力工作,如果有,则需要几周时间, 为自己带来巨大的压力,祝你好运。我做了类似的事情。这是一个杀手。

如果你想要一个开箱即用的解决方案,那么问题的答案是否定的,除非标题为你提供编码器字段,并且编码器是独特的,并且已知只用于进行环绕立体声转换。 我认为没有人像我描述的那样从实际数据中做到这一点,或者如果他们这样做,它是商业产品的一部分。通常不需要做你想做的事,但可以做到。

噢,顺便说一句,尝试谷歌搜索HRTF倒置,它可能会给你一些帮助。