假设您计划开始播客。 您拥有录音设备、一个有趣的主题以及一个其他人想听的好声音。 您似乎正在顺利地填补着各处的耳机。
然后是托管播客的问题。 iTunes 需要 RSS Feed,以便它可以在您的剧集可用时将其分发给订阅者,但是您该怎么做呢? 好消息是,有许多方法可以托管播客。 例如,您可以使用托管服务,该服务通常会收取费用,并在一个整洁的地方为您提供存储和分发。 如果您使用 WordPress 并已经研究过播客,您可能已经看到所有可用的强大的播客插件。
在本篇文章中,我们将跳过这些选项,看看如何仅使用 WordPress 网站和两个附加文件来托管自己的播客。 具体来说,我们将
- 设置一个新插件
- 注册自定义 RSS Feed
- 为我们的播客创建自定义帖子类型
- 将自定义字段分配给我们的自定义帖子类型
- 创建 RSS Feed 模板
目标不是过度思考。 如果您已经拥有 WordPress 网站,并且您只需要一个提交通往 iTunes 的 Feed,那么我们就是要做这件事。 让我们开始吧。
设置插件
创建插件是主题 `functions.php` 文件中编写代码的一个不错的替代方法。 除了保持主题功能的整洁和无杂乱外,它还将播客 Feed 功能保存在 `/wp-content/plugins/` 目录中,即使您更改主题,它也会保留在那里。
创建插件目录
首先。 让我们在 `/wp-content/plugins/` 目录中创建一个名为 `my-awesome-podcast` 的新文件夹。
创建插件
现在,让我们在刚创建的文件夹中创建一个新的 PHP 文件,并将其命名为 `my-awesome-podcast.php`。 这将是注册插件的主要文件,也是我们为播客编写功能的地方。
有了这个文件,我们将添加以下代码注释,告诉 WordPress 插件的名称、描述和版本。 我们还可以添加 其他信息,但这已经足够了。
/**
Plugin Name: My Awesome Podcast
Description: A really simple RSS feed and custom post type for a podcast
Version: 1.0
**/
// This is where we will start writing our plugin
注册 RSS Feed
接下来,我们需要注册一个新的 RSS Feed。 谢天谢地,WordPress API 有一个方便的 add_feed() 函数,我们可以将其挂钩以使其相对容易。
add_action('init', 'podcast_rss');
function podcast_rss(){
add_feed('my-awesome-podcast', 'my_podcast_rss');
}
这里发生的事情是,我们定义了一个名为 `podcast_rss()` 的新函数,并扩展了 WordPress `add_feed()` 函数以创建一个名为“my_podcast_rss” 的新 RSS Feed,它将位于我们网站的 `/feed/my-awesome-podcast` 上。
注意: 您可以在此处将“my-awesome-podcast” 更改为您想要的任何内容。 这是 Feed 的 URL 标识符,因此它可以是您的播客标题或您喜欢的任何其他内容。
注册播客自定义帖子类型
创建 Feed 后,我们需要设置一个新的帖子类型,以便我们可以使用它来发布剧集的帖子。 因此,我们将创建一个名为“Podcast” 的全新帖子类型,而不是 WordPress 默认的“Post” 或“Page”。 WordPress Codex 对 如何创建自定义帖子类型 做了很好的解释,因此无需在此赘述。 甚至有一些插件可以做到这一点,如果您愿意的话,可以选择这样操作。 无论如何,假设我们没有插件的帮助,并在我们的文件中创建 Podcast 自定义帖子类型。
function custom_post_type() {
$labels = array(
'name' => _x( 'Podcasts', 'Podcast General Name', 'text_domain' ),
'singular_name' => _x( 'Podcast', 'Course Singular Name', 'text_domain' ),
'menu_name' => __( 'Podcasts', 'text_domain' ),
'parent_item_colon' => __( 'Parent Podcast:', 'text_domain' ),
'all_items' => __( 'All Podcasts', 'text_domain' ),
'view_item' => __( 'View Podcast', 'text_domain' ),
'add_new_item' => __( 'Add New Podcast', 'text_domain' ),
'add_new' => __( 'Add New', 'text_domain' ),
'edit_item' => __( 'Edit Podcast', 'text_domain' ),
'update_item' => __( 'Update Podcast', 'text_domain' ),
'search_items' => __( 'Search Podcasts', 'text_domain' ),
'not_found' => __( 'Not found', 'text_domain' ),
'not_found_in_trash' => __( 'Not found in Trash', 'text_domain' ),
);
$args = array(
'label' => __( 'podcasts', 'text_domain' ),
'description' => __( 'Podcast Description', 'text_domain' ),
'labels' => $labels,
'supports' => array( 'title', 'editor', 'thumbnail' ),
'taxonomies' => array( 'category', 'post_tag' ),
'hierarchical' => false,
'public' => true,
'show_ui' => true,
'show_in_menu' => true,
'show_in_nav_menus' => true,
'show_in_admin_bar' => true,
'menu_position' => 5,
'menu_icon' => 'dashicons-format-audio',
'can_export' => true,
'has_archive' => true,
'exclude_from_search' => false,
'publicly_queryable' => true,
'capability_type' => 'page'
);
register_post_type( 'podcasts', $args );
}
add_action( 'init', 'custom_post_type', 0 );
这段代码很多,但它只是注册名为 Podcast 的新帖子类型的配置。 它定义了 WordPress 仪表板中它的各种标签,并告诉 WordPress 如何处理它。 同样,如果您有兴趣,WordPress Codex 对这些内容进行了更详细的解释。
此时,我们可以进入 WordPress 管理员的插件部分,查看 **我的精彩播客** 是否已列为可用的插件。 继续并激活它。

为播客帖子创建自定义字段
WordPress 帖子开箱即用就能为我们做很多事情,但有时我们需要其他字段,以便我们可以发布特定内容。 在这种情况下,iTunes 对 RSS Feed 中需要提供哪些信息 有非常具体的格式要求。
通过额外的开发,有一种方法可以 将自定义字段添加到我们的自定义帖子类型 中,但我实际上更喜欢使用 Advanced Custom Fields 插件 来完成这类事情。 它使我们能够为添加的每个字段提供一个干净简洁的自定义 UI,而不是默认自定义字段提供的通用键值对 UI。
使用 Advanced Custom Fields,让我们设置一个名为 Podcast 的新字段组,将其分配给 Podcast 帖子类型,并创建以下字段

- podcast_file: 使用“File” 字段类型,以便我们可以将播客文件直接上传到帖子中。 将字段设置为返回值为“File ID”,因为这将有助于我们稍后自动检测文件大小。
- podcast_duration: 这是一个简单的文本字段,我们将使用它以 HH:MM:SS 格式发布剧集的长度。
注意: 虽然我在本示例中使用了“File” 字段类型,但理论上,如果您计划在服务器以外的其他地方托管播客文件(例如 Amazon S3),则可以使用文本字段,并将 URL 直接粘贴到其中。 但是,我们无法通过这种方式自动检测文件大小,尽管我们可以使用另一个文本字段来实现此目的。
创建 RSS 模板
到目前为止,我们已经做了很多。 最后要做的事情是创建用于显示播客帖子数据的模板。
Apple 概述了可接受的播客 RSS Feed 的规范,它非常具体。 使用该概述作为指南,让我们在插件文件夹中创建一个名为 `podcast-rss-template.php` 的文件。 顾名思义,对吧?
好消息是,我们的 RSS 模板在技术上与任何其他 WordPress 模板没有区别。 我们将查询我们的帖子,创建一个循环,并将我们的数据插入到需要的地方。
/**
Template Name: Podcast RSS
**/
// Query the Podcast Custom Post Type and fetch the latest 100 posts
$args = array( 'post_type' => 'podcasts', 'posts_per_page' => 100 );
$loop = new WP_Query( $args );
/**
* Get the current URL taking into account HTTPS and Port
* @link https://css-tricks.cn/snippets/php/get-current-page-url/
* @version Refactored by @AlexParraSilva
*/
function getCurrentUrl() {
$url = isset( $_SERVER['HTTPS'] ) && 'on' === $_SERVER['HTTPS'] ? 'https' : 'http';
$url .= '://' . $_SERVER['SERVER_NAME'];
$url .= in_array( $_SERVER['SERVER_PORT'], array('80', '443') ) ? '' : ':' . $_SERVER['SERVER_PORT'];
$url .= $_SERVER['REQUEST_URI'];
return $url;
}
// Output the XML header
header('Content-Type: '.feed_content_type('rss-http').'; charset='.get_option('blog_charset'), true);
echo '<?xml version="1.0" encoding="'.get_option('blog_charset').'"?'.'>';
?>
<?php // Start the iTunes RSS Feed: https://www.apple.com/itunes/podcasts/specs.html ?>
<rss xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" version="2.0">
<?php
// The information for the podcast channel
// Mostly using get_bloginfo() here, but these can be custom tailored, as needed
?>
<channel>
<title><?php echo get_bloginfo('name'); ?></title>
<link><?php echo get_bloginfo('url'); ?></link>
<language><?php echo get_bloginfo ( 'language' ); ?></language>
<copyright><?php echo date('Y'); ?> <?php echo get_bloginfo('name'); ?></copyright>
<itunes:author><?php echo get_bloginfo('name'); ?></itunes:author>
<itunes:summary><?php echo get_bloginfo('description'); ?></itunes:summary>
<description><?php echo get_bloginfo('url'); ?></description>
<itunes:owner>
<itunes:name><?php echo get_bloginfo('name'); ?></itunes:name>
<itunes:email><?php echo get_bloginfo('admin_email'); ?></itunes:email>
</itunes:owner>
<?php // Change to your own image. Must be at least 1400 x 1400: https://www.apple.com/itunes/podcasts/creatorfaq.html
<itunes:image href="http://your-site.com/path/to/podcast/image.png" />
<itunes:category text="Technology">
<itunes:category text="Tech News"/>
</itunes:category>
<itunes:explicit>yes</itunes:explicit>
<?php // Start the loop for Podcast posts
while ( $loop->have_posts() ) : $loop->the_post(); ?>
<item>
<title><?php the_title_rss(); ?></title>
<itunes:author><?php echo get_bloginfo('name'); ?></itunes:author>
<itunes:summary><?php echo get_the_excerpt(); ?></itunes:summary>
<?php // Retrieve just the URL of the Featured Image: http://codex.wordpress.org/Function_Reference/wp_get_attachment_image_src
if (has_post_thumbnail( $post->ID ) ): ?>
<?php $image = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'full' ); ?>
<itunes:image href="<?php echo $image[0]; ?>" />
<?php endif; ?>
<?php // Get the file field URL, filesize and date format
$attachment_id = get_field('podcast_file');
$fileurl = wp_get_attachment_url( $attachment_id );
$filesize = filesize( get_attached_file( $attachment_id ) );
$dateformatstring = _x( 'D, d M Y H:i:s O', 'Date formating for iTunes feed.' );
?>
<enclosure url="<?php echo $fileurl; ?>" length="<?php echo $filesize; ?>" type="audio/mpeg" />
<guid><?php echo $fileurl; ?></guid>
<guid><?php the_field('podcast_file'); ?></guid>
<pubDate><?php echo date($dateformatstring, $show_date); ?></pubDate>
<itunes:duration><?php the_field('podcast_duration'); ?></itunes:duration>
</item>
<?php endwhile; ?>
</channel>
</rss>
注意: 上面的代码假定您将 MP3 文件上传到您自己的网站/服务器。 在这种情况下,它可以获取以字节为单位的文件大小,iTunes 要求将其作为 RSS Feed 的一部分,这非常方便。 但是,如果您在其他地方托管 MP3 文件(可以很智能,大多数 Web 主机不是为提供大型资产而构建的),则此方法将不起作用。 相反,使用 ACF 添加一个额外的字段来表示字节大小,并在我们输出 `$filesize` 的地方输出它。
现在,让我们在 `my-awesome.podcast.php` 文件中调用此 RSS 模板,方法是添加以下内容
function my_podcast_rss(){
require_once( dirname( __FILE__ ) . '/podcast-rss-template.php' );
}
整合所有内容
让我们回顾一下所有内容是如何组合在一起的。
文件
简而言之,我们现在在插件目录中有一个名为 `my-awesome-podcast` 的新文件夹。
WordPress Root Directory
└── wp-content
└── plugins
└── my-awesome-podcast
├── my-awesome-podcast.php
└── podcast-rss-template.php
- my-awesome.podcast.php: 此文件注册我们的插件,创建自定义 RSS 订阅源,定义新的自定义帖子类型并调用我们的 RSS 模板。
- podcast-rss-template.php: 此文件包含我们的 RSS 订阅源的模板,以 iTunes 可读的格式提供我们 Podcast 帖子的信息,并用于将我们的内容传递给订阅者。
发布播客
继续发布新的 Podcast 帖子。选项将在 WordPress 菜单的 Podcast 下。

- 为播客取一个标题
- 上传播客剧集文件
- 指定剧集时长(以 HH:MM:SS 格式)
- (如果不在本地托管)指定剧集文件大小(以字节为单位)
- 在内容区域提供剧集摘要
太棒了,我们刚刚发布了你的第一集播客!
将播客提交到 iTunes
最后,访问该订阅源的 URL:`[your-site]/feed/[slug]`,其中 `[slug]` 是我们在第二步的 `add_feed()` 函数中定义的。验证该订阅源不会有什么坏处 validate the feed 只要确保它健康快乐。这是你提交给 iTunes 的 URL,你可以从 iTunes 应用程序中的 iTunes Store > Podcast > 快速链接 > 提交播客中进行操作。
如果你遇到页面未找到 (404),尝试刷新你的永久链接。这可以通过从 WordPress 仪表板转到设置 > 永久链接来完成,只需要点击保存设置按钮即可。很奇怪,但确实如此。
开始播客
就是这样!一种简单但有效的利用你可能已经拥有的资源来托管播客的方法。当然,可能会有更强大甚至更优雅的解决方案,但这为我们提供了我们所需的一切,不多也不少。
更新:向 David Scanu 表示衷心的感谢。他提供了一些更新,以更正一些 RSS 验证问题,这些问题现在已反映在文章中。非常感谢!
我有一个想法可以简化体验:让软件获取播客的时间。有几种方法可以做到这一点,但 这个简单的类 似乎可以做到这一点,而无需依赖巨大的代码库(例如巨大的 getId3() 库)。但是,如果你使用 AAC(MP4)或其他格式的播客,getId3 似乎是最好的选择之一。(如果正确标记文件,你甚至可以从文件中提取更多信息,但这超出了本文的范围。)
不错!我以前没见过那个类——绝对有用,尤其是在一些用户无法使用 ACF 的情况下。
感谢你写这篇很棒的文章,Geoff!对我来说,这真是 完美 的时机,因为我即将在我的当前项目中构建播客功能,而现有的播客插件并不完全满足我的需求。
我将使用单个帖子模板,以便人们可以访问网站并在浏览器中收听。你如何让内置的 WP 音频播放器与 `<?php the_field('podcast_file'); ?>` 配合使用?
好问题!我想你可以使用
do_shortcode()
函数在模板中插入音频播放器,然后将我们在 RSS 模板中定义的 `$fileurl` 变量作为音频播放器的源文件回显。谢谢,Geoff。我考虑过
do_shortcode()
,但不知道是否还有更好的方法。奇怪的是,没有简单的方法可以自动获取持续时间,因为内置的音频播放器可以做到这一点。我查看了
wp_read_audio_metadata
,但没有看到关于获取持续时间的任何内容。我希望不必让多个贡献者每次都输入持续时间,这既是为了方便,也是为了避免错误。很棒的文章!这是我读过的关于创建简单插件的最佳文章之一。它功能齐全,功能丰富,并解决了许多用户遇到的问题。
注意:在“创建 Podcast 帖子的自定义字段”部分,Advanced Custom Fields 插件的链接似乎不起作用。
谢谢!我很高兴你觉得这有用。:)
你找到了正确的链接。为了记录,这是正确的链接:http://www.advancedcustomfields.com/
好文章,但我建议使用 Podlove Publisher 来使用 WordPress 发布播客
http://podlove.org/podlove-podcast-publisher/
这太棒了。我们在 http://realwpsite.com 的 Podcast 插件中使用了非常类似的自定义解决方案。
感谢你写这篇很棒且实用的文章,Geoff!我计划在我的 WordPress 个人网站上推出我自己的播客,就在我看到这篇很棒的文章的时候,我会尽力尽快推出它。
Jeff