2022年 11月 3日

python 传智播客_使用Python自动播客发布

python 传智播客

我有一个播客 ,可与Red Hat同事和各种行业专家聊天,涉及从云到DevOps到容器再到IoT到开源的话题。 随着时间的流逝,我已经大大简化了录制和编辑过程 。 但是,当涉及将播客实际在线放置的机制时,需要精确遵循许多繁琐的小步骤。 我确信任何正在阅读此内容的系统管理员都已经在“您需要一个脚本!” 他们是完全正确的。

在本文中,我将带您看一下我编写的Python脚本,该脚本在很大程度上可以自动编辑播客。 该脚本无法完成所有任务。 我仍然需要输入特定于剧集的信息才能应用该脚本,并且我会手工撰写博客文章。 (我曾经使用脚本为博客创建一个存根,但是该操作的那部分需要足够的手动步骤,以至于我没有买到任何东西。)尽管如此,该脚本仍处理了许多琐碎的小步骤否则会很耗时且容易出错。

我会警告您,这是我几年前针对特定工作流程编写的一个基本程序。 您将需要根据自己的需要进行定制。 此外,尽管出于本文的目的,我对代码进行了一些整理,但它并不包含大量输入或错误检查,并且其用户界面非常基本。

该脚本有六件事。 它:

  • 提供一个界面供用户输入剧集标题,字幕和摘要;
  • 从MP3文件中获取信息(例如持续时间);
  • 更新XML播客feed文件;
  • 将原始编辑的MP3文件与前段和后段连接在一起;
  • 创建一个OGG文件版本;
  • 并将XML,MP3和OGG文件上传到Amazon S3并使其公开。

podcast-python脚本

如果您想下载阅读本文时要参考的全部内容,可以在GitHub上使用podcast-python脚本 。

潜水之前,要整理一点。 我们将boto用于Amazon Web Services S3界面,其中将存储使播客公开可用所需的文件。 我们将使用mpeg1audio从MP3文件中检索元数据。 最后,我们将使用pydub作为操作音频文件的界面,这需要在系统上安装ffmpeg 。

现在,您需要创建一个文本文件,其中包含整个播客的信息。 添加情节时不会改变。 下面的示例来自我的Cloudy Chat播客 。

  1. < ?
  2. xml version
  3. =
  4. "1.0" encoding
  5. =
  6. "UTF-8" ?
  7. >
  8. < rss xmlns:itunes
  9. =
  10. "http://www.itunes.com/dtds/podcast-1.0.dtd" version
  11. =
  12. "2.0"
  13. >
  14. < channel
  15. >
  16. < title
  17. > Cloudy Chat
  18. < /title
  19. >
  20. < link
  21. > http://www.
  22. bitmasons .
  23. com
  24. < /link
  25. >
  26. < language
  27. > en-us
  28. < /language
  29. >
  30. < copyright
  31. > &
  32. #x2117; &amp; &#xA9; 2017, Gordon Haff</copyright>
  33. < itunes:subtitle
  34. > Industry experts talk cloud computing
  35. < /itunes:subtitle
  36. >
  37. < itunes:author
  38. > Gordon Haff
  39. < /itunes:author
  40. >
  41. < itunes:summary
  42. > Information technology today
  43. is at the explosive intersection of major trends that are fundamentally changing how we do computing
  44. and ultimately interact
  45. with the world.
  46. Longtime industry expert
  47. , pundit
  48. ,
  49. and now Red Hat cloud evangelist Gordon Haff examines these changes through conversations
  50. with leading technologists
  51. and visionaries.
  52. < /itunes:summary
  53. >
  54. < description
  55. > Industry experts talk cloud computing
  56. , DevOps
  57. , IoT
  58. , containers
  59. ,
  60. and more.
  61. < /description
  62. >
  63. < itunes:owner
  64. >
  65. < itunes:name
  66. > Gordon Haff
  67. < /itunes:name
  68. >
  69. < itunes:email
  70. > REDACTED
  71. @ gmail.
  72. com
  73. < /itunes:email
  74. >
  75. < /itunes:owner
  76. >
  77. < itunes:image href
  78. =
  79. "http://s3.amazonaws.com/grhpodcasts/cloudychat300.jpg" /
  80. >
  81. < itunes:category text
  82. =
  83. "Technology" /
  84. >
  85. < itunes:explicit
  86. > no
  87. < /itunes:explicit
  88. >

然后,您需要一个第二个文本文件,其中包含每个现有项目(例如,情节)的XML,外加几行。 如果您没有任何现有情节,则文件将如下所示。

  1. < /channel
  2. >
  3. < /rss
  4. >

该脚本通过将标题文本与新剧集的XML连接起来,然后附加第二个文本文件,来构建您的播客feed文件。 然后,它还将新项目添加到第二个文本文件,以便在添加另一个新剧集时将其存在。

该程序使用TkInter (位于Tcl / Tk之上的一个薄的面向对象层)作为GUI。 除了选择要上传的MP3文件之外,您还可以在此处输入播客标题,副标题和摘要。 它作为主程序循环运行,如下图所示:

screenshot

这是使用以下代码构建的。 (您可能应该使用较新的TkInter主题小部件,但我从来没有更新到更漂亮的界面。)

  1. root
  2. = Tk
  3. (
  4. )
  5. Label
  6. ( root
  7. , text
  8. =
  9. "Podcast Title:"
  10. ) .
  11. grid
  12. ( row
  13. =
  14. 1
  15. , sticky
  16. = W
  17. )
  18. < Some interface building
  19. code omitted
  20. >
  21. Button
  22. ( root
  23. , text
  24. =
  25. 'Select file...'
  26. , command
  27. = open_file_dialog
  28. ) .
  29. grid
  30. ( row
  31. =
  32. 9
  33. , column
  34. =
  35. 0
  36. , sticky
  37. = W
  38. )
  39. v
  40. = StringVar
  41. (
  42. )
  43. Label
  44. ( root
  45. , textvariable
  46. = v
  47. , justify
  48. = LEFT
  49. , fg
  50. =
  51. "blue"
  52. ) .
  53. grid
  54. ( row
  55. =
  56. 10
  57. , sticky
  58. = W
  59. )
  60. TimestampEntry
  61. = Entry
  62. ( root
  63. , width
  64. =
  65. 50
  66. , borderwidth
  67. =
  68. 1
  69. ) TimestampEntry.
  70. grid
  71. ( row
  72. =
  73. 11
  74. , sticky
  75. = W
  76. )
  77. TimestampEntry.
  78. insert
  79. ( END
  80. ,
  81. "Time/date (default filled in automatically from file)"
  82. )
  83. FilelengthStr
  84. = StringVar
  85. (
  86. ) FilelengthStr.
  87. set
  88. (
  89. "Filelength (bytes):"
  90. )
  91. FilelengthLabel
  92. = Label
  93. ( root
  94. , textvariable
  95. = FilelengthStr
  96. )
  97. FilelengthLabel.
  98. grid
  99. ( row
  100. =
  101. 12
  102. , sticky
  103. = W
  104. )
  105. DurationLabelStr
  106. = StringVar
  107. (
  108. )
  109. DurationLabelStr.
  110. set
  111. (
  112. "Duration: "
  113. )
  114. ; DurationLabel
  115. = Label
  116. ( root
  117. , textvariable
  118. = DurationLabelStr
  119. ) DurationLabel.
  120. grid
  121. ( row
  122. =
  123. 13
  124. , sticky
  125. = W
  126. )
  127. Button
  128. ( root
  129. , text
  130. =
  131. 'Go!'
  132. , command
  133. = do_stuff
  134. ) .
  135. grid
  136. ( row
  137. =
  138. 14
  139. , sticky
  140. = W
  141. )
  142. StatusText
  143. = StringVar
  144. (
  145. ) StatusText.
  146. set
  147. (
  148. "Status: Nothing to report"
  149. )
  150. StatusLabel
  151. = Label
  152. ( root
  153. , textvariable
  154. = StatusText
  155. ) StatusLabel.
  156. grid
  157. ( row
  158. =
  159. 15
  160. , sticky
  161. = W
  162. )
  163. root.
  164. mainloop
  165. (
  166. )

当我们选择一个MP3文件时, open_file_dialog函数将运行。 此函数执行所有音频文件操作,然后通过全局变量将所需的有关文件大小,长度和日期戳的信息返回到界面中的标签小部件。 首先进行操作更为直接,因为我们要获取适用于将要上传的最终文件的元数据。 根据文件大小,此操作可能需要一分钟左右的时间。

去吧! 按钮然后执行发布播客所需的其余功能,并在该过程似乎已成功完成时返回状态。

借助这些初步知识,让我们看一下脚本执行的一些特定任务。 我将主要跳过与设置目录路径和类似内容相关的内务管理细节,而将重点放在实际的自动化上。

添加简介和结尾。 节省时间:每集5分钟。

我们要做的第一件事是备份原始文件。 如果出现问题,这是个好习惯。 它也给了我基本文件的副本,以便照常发送出去。

  1. renameOriginal
  2. = FileBase +
  3. "_original" + FileExtension  
  4. shutil .
  5. copy2
  6. ( filename
  7. , renameOriginal
  8. )

然后,我将MP3文件与前奏和后奏音频连接在一起。 AudioSegment是pydub函数。

  1. baseSegment
  2. = AudioSegment.
  3. from_mp3
  4. ( filename
  5. )   
  6. introSegment
  7. = AudioSegment.
  8. from_mp3
  9. ( leadIn
  10. )
  11. outroSegment
  12. = AudioSegment.
  13. from_mp3
  14. ( leadOut
  15. )
  16. completeSegment
  17. = introSegment + baseSegment + outroSegment
  18. completeSegment.
  19. export
  20. ( filename
  21. ,
  22. "mp3"
  23. )

前奏和尾奏是我用来引导和关闭播客的标准音频片段。 它们由简短的人声段和几秒钟的音乐组成。 手动添加这些内容至少需要几分钟,并且可能会添加错误的剪辑。 我还创建了一个OGG版本的播客,可以从我的博客链接到该播客以及MP3文件。

获取文件元数据。 节省时间:每集3分钟。

我们新获得了文件的大小,时间,日期和长度,并将其全部转换为播客feed所需的格式。 大小和时间戳来自标准函数。 mpeg1audio提供MP3文件的持续时间。

  1. Filelength
  2. = path.
  3. getsize
  4. ( filename
  5. )
  6. FilelengthStr.
  7. set
  8. (
  9. "Filelength (bytes): " +
  10. str
  11. ( Filelength
  12. )
  13. )
  14. timestruc
  15. =
  16. time .
  17. gmtime
  18. ( path.
  19. getmtime
  20. ( filename
  21. )
  22. )
  23. TimestampEntry.
  24. delete
  25. (
  26. 0
  27. , END
  28. )
  29. TimestampEntry.
  30. insert
  31. (
  32. 0
  33. ,
  34. time .
  35. strftime
  36. (
  37. "%a, %d %b %G %T"
  38. , timestruc
  39. ) +
  40. " GMT"
  41. )
  42. mp3
  43. = mpeg1audio.
  44. MPEGAudio
  45. ( filename
  46. )
  47. DurationStr
  48. =
  49. str
  50. ( mp3.
  51. duration
  52. )
  53. DurationLabelStr.
  54. set
  55. (
  56. "Duration: " + DurationStr
  57. )

构建播客feed XML文件。 节省时间:每集8分钟。

这确实是一个巨大的胜利。 启动文本编辑器和编辑XML文件所花费的时间甚至不多。 就是因为我经常在第一次尝试时就弄错了。 而且,由于我经常在第一次尝试时就弄错了,因此当我手动编辑文件时,我不得不在上传之前先通过XML验证程序运行该文件。

现在,出于全面披露的目的,我应该注意,编写的脚本对如果字符(例如&符)在供稿中必须转义的字符没有任何作用。 由于不同的原因,如果您将诸如卷曲引号之类的字符剪切并粘贴到“ 摘要”编辑框中,则可能也会遇到问题。 但是,总的来说,我可以放心地将请求的信息输入到GUI中,并可以确信提要是干净的。

  1. # create an XML file containing contents for new </item> for iTunes   
  2. FileBase
  3. , FileExtension
  4. = path.
  5. splitext
  6. ( filename
  7. )   
  8. XMLfilename
  9. = FileBase +
  10. '.xml'   
  11. MP3url
  12. =
  13. "http://s3.amazonaws.com/" +bucket_name+
  14. "/" +path.
  15. basename
  16. ( filename
  17. )   
  18. inp
  19. =
  20. file
  21. ( XMLfilename
  22. ,
  23. 'w'
  24. )
  25. inp.
  26. write
  27. (
  28. "<item> \n "
  29. )   
  30. inp.
  31. write
  32. (
  33. "<title>" +PodcastTitleEntry.
  34. get
  35. (
  36. ) +
  37. "</title> \n "
  38. )   
  39. inp.
  40. write
  41. (
  42. "<itunes:subtitle>" +PodcastSubtitleEntry.
  43. get
  44. (
  45. ) +
  46. "</itunes:subtitle> \n "
  47. )   
  48. inp.
  49. write
  50. (
  51. "<itunes:summary>" +PodcastSummaryText.
  52. get
  53. (
  54. 1.0
  55. , END
  56. ) +
  57. "</itunes:summary> \n "
  58. )   
  59. inp.
  60. write
  61. (
  62. "<enclosure url= \" " +MP3url+
  63. " \" length= \" " +
  64. str
  65. ( Filelength
  66. ) +
  67. " \" type= \" audio/mpeg \" /> \n "
  68. )   
  69. inp.
  70. write
  71. (
  72. "<guid>" +MP3url+
  73. "</guid> \n "
  74. )   
  75. inp.
  76. write
  77. (
  78. "<pubDate>" +TimestampEntry.
  79. get
  80. (
  81. ) +
  82. "</pubDate> \n "
  83. )   
  84. inp.
  85. write
  86. (
  87. "<itunes:duration>" +DurationStr+
  88. "</itunes:duration> \n "
  89. )   
  90. inp.
  91. write
  92. (
  93. "<itunes:keywords>cloud</itunes:keywords> \n "
  94. )   
  95. inp.
  96. write
  97. (
  98. "<itunes:explicit>no</itunes:explicit> \n "
  99. )   
  100. inp.
  101. write
  102. (
  103. "</item>"
  104. )   
  105. inp.
  106. write
  107. (
  108. ""
  109. )
  110. inp.
  111. close
  112. (
  113. )
  114. #Now concatenate to make a new itunesxml.xml file       
  115. #create backup of existing iTunes XML file in case something goes kaka   
  116. iTunesBackup
  117. = path.
  118. join
  119. ( theDirname
  120. ,
  121. "itunesxmlbackup.xml"
  122. )   
  123. shutil .
  124. copy2
  125. ( iTunesFile
  126. , iTunesBackup
  127. )
  128. #create temporary iTunes item list (to overwrite the old one later on)       
  129. outfile
  130. =
  131. file
  132. (
  133. "iTunestemp.xml"
  134. ,
  135. 'w'
  136. )       
  137. # create a new items file   
  138. with
  139. open
  140. ( XMLfilename
  141. )
  142. as f:       
  143.    
  144. for line
  145. in f:           
  146.         outfile.
  147. write
  148. ( line
  149. )   
  150. with
  151. open
  152. ( iTunesItems
  153. )
  154. as f:       
  155.    
  156. for line
  157. in f:           
  158.         outfile.
  159. write
  160. ( line
  161. )    
  162. outfile.
  163. close
  164. (
  165. )           
  166. #replace the old items file with the new one   
  167. shutil .
  168. copy2
  169. (
  170. "iTunestemp.xml"
  171. , iTunesItems
  172. )       
  173. #now we're ready to create the new iTunes File     
  174. outfile
  175. =
  176. file
  177. ( iTunesFile
  178. ,
  179. 'w'
  180. )       
  181. # create a new items file   
  182. with
  183. open
  184. ( iTunesHeader
  185. )
  186. as f:       
  187.    
  188. for line
  189. in f:           
  190.         outfile.
  191. write
  192. ( line
  193. )   
  194. with
  195. open
  196. ( iTunesItems
  197. )
  198. as f:       
  199.    
  200. for line
  201. in f:           
  202.         outfile.
  203. write
  204. ( line
  205. )    
  206. outfile.
  207. close
  208. (
  209. )

上载到AWS S3。 节省时间:每集5分钟。

我们有修改后的音频文件,还有提要文件-是时候将它们放置在全世界可以听的地方了。 我使用boto连接到AWS S3并上传文件。

这很简单。 您连接到S3。 在此脚本中,假定AWS凭证存储在您的环境中。 boto的当前版本boto3提供了许多处理凭据的替代方法。 然后将文件上传并公开。

如果您要尝试使用现有播客进行自动化操作,最好给Feed文件提供一个与现有Feed不冲突的名称,然后将文件上传为私有文件。 这使您有机会在上线之前手动检查一切正常。 那是我一开始所做的。 随着时间的流逝,我进行了一些调整,并获得了信心,我可以开除并且(大部分)忘记。

我经常仍然快速浏览一下以确认没有问题,但是老实说,这些天很少出现问题。 而且,如果我听取自己的建议,我将花一些时间来解决一些我所知道的潜在潜在故障,特别是验证和清理输入。

  1. # Upload files to Amazon S3   
  2. # Change 'public-read' to 'private' if you want to manually set ACLs   
  3. conn
  4. = boto.
  5. connect_s3
  6. (
  7. )   
  8. bucket
  9. = conn.
  10. get_bucket
  11. ( bucket_name
  12. )   
  13. k
  14. = Key
  15. ( bucket
  16. )   
  17. k.
  18. key
  19. = path.
  20. basename
  21. ( filename
  22. )   
  23. k.
  24. set_contents_from_filename
  25. ( filename
  26. )   
  27. k.
  28. set_canned_acl
  29. (
  30. 'public-read'
  31. )
  32.    
  33. k.
  34. key
  35. = path.
  36. basename
  37. ( iTunesFile
  38. )   
  39. k.
  40. set_contents_from_filename
  41. ( iTunesFile
  42. )   
  43. k.
  44. set_canned_acl
  45. (
  46. 'public-read'
  47. )

节省时间

那么,这会把我们留在哪里呢? 如果我总计节省的时间估计,则每集21分钟。 当然,这仍然需要我几分钟,但其中大部分是用文字描述剧集,无论如何都需要完成。 即使我们为每集分配不那么慷慨的15分钟节省时间,这也算是1,500分钟(25 小时)的不错时间,通过花一天左右的时间来编写脚本,我已经节省了100多个播客。

但是,老实说,我不确定即使那个时间的数字也能捕捉到现实。 反复地,繁琐的工作破坏了一天并消耗了精力。 自动化一切都没有意义。 但是,通常,如果您愿意尝试自动执行经常执行的操作,则不会后悔。

翻译自: https://opensource.com/article/17/4/automate-podcast-publishing-python

python 传智播客