{"id":272058,"date":"2025-03-06T05:26:14","date_gmt":"2025-03-06T05:26:14","guid":{"rendered":"https:\/\/michigandigitalnews.com\/index.php\/2025\/03\/06\/common-media-processing-operations-with-jetpack-media3-transformer\/"},"modified":"2025-06-25T17:09:13","modified_gmt":"2025-06-25T17:09:13","slug":"common-media-processing-operations-with-jetpack-media3-transformer","status":"publish","type":"post","link":"https:\/\/michigandigitalnews.com\/index.php\/2025\/03\/06\/common-media-processing-operations-with-jetpack-media3-transformer\/","title":{"rendered":"Common media processing operations with Jetpack Media3 Transformer"},"content":{"rendered":"<p> [ad_1]<br \/>\n<\/p>\n<div>\n<meta content=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEifgV_wUMIzInKtKXR9FyNh7h00qDygaA6fRVDMqMxht68oPNmrAJfZtM_Vf6-3VD8FVGKoSoljaILjtn7ygMwCdBcXPJAvH3fUWiw2LfZBHh4qFSrMvOZLqlDiPVILmiBBo8jKZb0izoq0jxA1tFR9MKf5tDr112svVgsIhdxNnQTK8xf1n7GyduQYT9Q\/s1600\/Jetpack-Media3-Processing.png\" name=\"twitter:image\"\/><br \/>\n<img decoding=\"async\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEifgV_wUMIzInKtKXR9FyNh7h00qDygaA6fRVDMqMxht68oPNmrAJfZtM_Vf6-3VD8FVGKoSoljaILjtn7ygMwCdBcXPJAvH3fUWiw2LfZBHh4qFSrMvOZLqlDiPVILmiBBo8jKZb0izoq0jxA1tFR9MKf5tDr112svVgsIhdxNnQTK8xf1n7GyduQYT9Q\/s1600\/Jetpack-Media3-Processing.png\" style=\"display: none;\"\/><\/p>\n<p><em>Posted by Nevin Mital \u2013 Developer Relations Engineer, and Kristina Simakova \u2013 Engineering Manager<\/em><\/p>\n<p><a href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEiiJNdGSk1eFCtZbcQJl7Tj-8Adto42Rn6bHT2EOkkRFVKklpyoZmZHtUkACfnbIbSotZv2oyJwSiMCrM2KJ5e_OyqwWMbXyTxuWoht755j540OGyWthdBM2PQBsFs12X9cVk9OiASFgfRgDCfRn6R-hTrB7st-V5wUqlmUi15THdsRXAtUWtWAY1vonyI\/s1600\/Jetpack-Media3-Processing%20%281%29.png\"><img decoding=\"async\" border=\"0\" data-original-height=\"800\" data-original-width=\"100%\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEiiJNdGSk1eFCtZbcQJl7Tj-8Adto42Rn6bHT2EOkkRFVKklpyoZmZHtUkACfnbIbSotZv2oyJwSiMCrM2KJ5e_OyqwWMbXyTxuWoht755j540OGyWthdBM2PQBsFs12X9cVk9OiASFgfRgDCfRn6R-hTrB7st-V5wUqlmUi15THdsRXAtUWtWAY1vonyI\/s1600\/Jetpack-Media3-Processing%20%281%29.png\"\/><\/a><\/p>\n<p>Android users have demonstrated an increasing desire to create, personalize, and share video content online, whether to preserve their memories or to make people laugh. As such, media editing is a cornerstone of many engaging Android apps, and historically developers have often relied on external libraries to handle operations such as Trimming and Resizing. While these solutions are powerful, integrating and managing external library dependencies can introduce complexity and lead to challenges with managing performance and quality.<\/p>\n<p>The Jetpack Media3 Transformer APIs offer a native Android solution that streamline media editing with fast performance, extensive customizability, and broad device compatibility. In this blog post, we\u2019ll walk through some of the most common editing operations with Transformer and discuss its performance.<\/p>\n<h2><span style=\"font-size: x-large;\">Getting set up with Transformer<\/span><\/h2>\n<p>To get started with Transformer, check out our <a href=\"https:\/\/developer.android.com\/media\/media3\/transformer\/getting-started\" target=\"_blank\" rel=\"noopener\">Getting Started<\/a> documentation for details on how to add the dependency to your project and a basic understanding of the workflow when using Transformer. In a nutshell, you\u2019ll:<\/p>\n<ul>\n<ul>\n<li>Create one or many <span style=\"font-family: courier;\"><a href=\"https:\/\/developer.android.com\/reference\/androidx\/media3\/common\/MediaItem\" target=\"_blank\" rel=\"noopener\">MediaItem<\/a><\/span> instances from your video file(s), then<\/li>\n<\/ul>\n<ul>\n<li>Apply item-specific edits to them by building an <span style=\"font-family: courier;\"><a href=\"https:\/\/developer.android.com\/reference\/androidx\/media3\/transformer\/EditedMediaItem\" target=\"_blank\" rel=\"noopener\">EditedMediaItem<\/a><\/span> for each <span style=\"color: #0d904f; font-family: courier;\">MediaItem<\/span>,<\/li>\n<\/ul>\n<ul>\n<li>Create a <span style=\"font-family: courier;\"><a href=\"https:\/\/developer.android.com\/reference\/androidx\/media3\/transformer\/Transformer\" target=\"_blank\" rel=\"noopener\">Transformer<\/a><\/span> instance configured with settings applicable to the whole exported video,<\/li>\n<\/ul>\n<ul>\n<li>and finally start the <a href=\"https:\/\/developer.android.com\/reference\/androidx\/media3\/transformer\/Transformer#start%28androidx.media3.transformer.EditedMediaItem,java.lang.String%29\" target=\"_blank\" rel=\"noopener\">export<\/a> to save your applied edits to a file.\n<\/li>\n<\/ul>\n<\/ul>\n<blockquote><p><b>Aside:<\/b> You can also use a <span style=\"font-family: courier;\"><a href=\"https:\/\/github.com\/androidx\/media\/blob\/release\/libraries\/transformer\/src\/main\/java\/androidx\/media3\/transformer\/CompositionPlayer.java\" target=\"_blank\" rel=\"noopener\">CompositionPlayer<\/a><\/span> to preview your edits before exporting, but this is out of scope for this blog post, as this API is still a work in progress. Please stay tuned for a future post!<\/p><\/blockquote>\n<p>Here\u2019s what this looks like in code:<\/p>\n<p><!--Kotlin--><\/p>\n<div style=\"background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;\">\n<pre style=\"line-height: 125%; margin: 0px;\"><span style=\"color: green; font-weight: bold;\">val<\/span> mediaItem = MediaItem.Builder().setUri(mediaItemUri).build()\n<span style=\"color: green; font-weight: bold;\">val<\/span> editedMediaItem = EditedMediaItem.Builder(mediaItem).build()\n<span style=\"color: green; font-weight: bold;\">val<\/span> transformer = \n  Transformer.Builder(context)\n    .addListener(<span style=\"color: #408080; font-style: italic;\">\/* Add a Transformer.Listener instance here for completion events *\/<\/span>)\n    .build()\ntransformer.start(editedMediaItem, outputFilePath)\n<\/pre>\n<\/div>\n<h2><span style=\"font-size: x-large;\">Transcoding, Trimming, Muting, and Resizing with the Transformer API<\/span><\/h2>\n<p>Let\u2019s now take a look at four of the most common single-asset media editing operations, starting with <i>Transcoding<\/i>.<\/p>\n<p><b>Transcoding<\/b> is the process of re-encoding an input file into a specified output format. For this example, we\u2019ll request the output to have video in HEVC (H265) and audio in AAC. Starting with the code above, here are the lines that change:<\/p>\n<p><!--Kotlin--><\/p>\n<div style=\"background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;\">\n<pre style=\"line-height: 125%; margin: 0px;\"><span style=\"color: green; font-weight: bold;\">val<\/span> transformer = \n  Transformer.Builder(context)\n    .addListener(...)\n    .<b>setVideoMimeType(MimeTypes.VIDEO_H265)\n    .setAudioMimeType(MimeTypes.AUDIO_AAC)<\/b>\n    .build()\n<\/pre>\n<\/div>\n<p>Many of you may already be familiar with <a href=\"https:\/\/www.ffmpeg.org\/\" target=\"_blank\" rel=\"noopener\">FFmpeg<\/a>, a popular open-source library for processing media files, so we\u2019ll also include FFmpeg commands for each example to serve as a helpful reference. Here\u2019s how you can perform the same transcoding with FFmpeg:<\/p>\n<p><!--Unset--><\/p>\n<div style=\"background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;\">\n<pre style=\"line-height: 125%; margin: 0px;\">$ ffmpeg <span style=\"color: #666666;\">-<\/span>i <span style=\"color: #19177c;\">$inputVideoPath<\/span> <b><span style=\"color: #666666;\">-<\/span>c<span style=\"color: #666666;\">:<\/span>v libx265 <span style=\"color: #666666;\">-<\/span>c<span style=\"color: #666666;\">:<\/span>a aac<\/b> <span style=\"color: #19177c;\">$outputFilePath<\/span>\n<\/pre>\n<\/div>\n<p>The next operation we\u2019ll try is <b>Trimming<\/b>.<\/p>\n<p>Specifically, we\u2019ll set Transformer up to trim the input video from the 3 second mark to the 8 second mark, resulting in a 5 second output video. Starting again from the code in the \u201cGetting set up\u201d section above, here are the lines that change:<\/p>\n<p><!--Kotlin--><\/p>\n<div style=\"background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;\">\n<pre style=\"line-height: 125%; margin: 0px;\"><span style=\"color: #408080; font-style: italic;\">\/\/ Configure the trim operation by adding a ClippingConfiguration to<\/span>\n<span style=\"color: #408080; font-style: italic;\">\/\/ the media item<\/span>\n<span style=\"color: green; font-weight: bold;\">val<\/span> <b>clippingConfiguration =\n   MediaItem.ClippingConfiguration.Builder()\n     .setStartPositionMs(<span style=\"color: #666666;\">3000<\/span>)\n     .setEndPositionMs(<span style=\"color: #666666;\">8000<\/span>)\n     .build()<\/b>\n<span style=\"color: green; font-weight: bold;\">val<\/span> mediaItem =\n   MediaItem.Builder()\n     .setUri(mediaItemUri)\n     .<b>setClippingConfiguration(clippingConfiguration)<\/b>\n     .build()\n\n<span style=\"color: #408080; font-style: italic;\">\/\/ Transformer also has a trim optimization feature we can enable.<\/span>\n<span style=\"color: #408080; font-style: italic;\">\/\/ This will prioritize Transmuxing over Transcoding where possible.<\/span>\n<span style=\"color: #408080; font-style: italic;\">\/\/ See more about Transmuxing further down in this post.<\/span>\n<span style=\"color: green; font-weight: bold;\">val<\/span> transformer = \n  Transformer.Builder(context)\n    .addListener(...)\n    <b>.experimentalSetTrimOptimizationEnabled(<span style=\"color: green;\">true<\/span>)<\/b>\n    .build()\n<\/pre>\n<\/div>\n<p>With FFmpeg:<\/p>\n<p><!--Unset--><\/p>\n<div style=\"background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;\">\n<pre style=\"line-height: 125%; margin: 0px;\">$ ffmpeg <b><span style=\"color: #666666;\">-<\/span>ss <span style=\"color: #666666;\">00:00:03<\/span><\/b> <span style=\"color: #666666;\">-<\/span>i <span style=\"color: #19177c;\">$inputVideoPath<\/span> <b><span style=\"color: #666666;\">-<\/span>t <span style=\"color: #666666;\">00:00:05<\/span><\/b> <span style=\"color: #19177c;\">$outputFilePath<\/span>\n<\/pre>\n<\/div>\n<p>Next, we can <b>mute<\/b> the audio in the exported video file.<\/p>\n<p><!--Kotlin--><\/p>\n<div style=\"background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;\">\n<pre style=\"line-height: 125%; margin: 0px;\"><span style=\"color: green; font-weight: bold;\">val<\/span> editedMediaItem = \n  EditedMediaItem.Builder(mediaItem)\n    <b>.setRemoveAudio(<span style=\"color: green;\">true<\/span>)<\/b>\n    .build()\n<\/pre>\n<\/div>\n<p>The corresponding FFmpeg command:<\/p>\n<p><!--Unset--><\/p>\n<div style=\"background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;\">\n<pre style=\"line-height: 125%; margin: 0px;\">$ ffmpeg <span style=\"color: #666666;\">-<\/span>i <span style=\"color: #19177c;\">$inputVideoPath<\/span> <b><span style=\"color: #666666;\">-<\/span>c copy <span style=\"color: #666666;\">-<\/span>an<\/b> <span style=\"color: #19177c;\">$outputFilePath<\/span>\n<\/pre>\n<\/div>\n<p>And for our final example, we\u2019ll try <b>resizing<\/b> the input video by scaling it down to half its original height and width.<\/p>\n<p><!--Kotlin--><\/p>\n<div style=\"background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;\">\n<pre style=\"line-height: 125%; margin: 0px;\"><span style=\"color: green; font-weight: bold;\">val<\/span> <b>scaleEffect = \n  ScaleAndRotateTransformation.Builder()\n    .setScale(<span style=\"color: #666666;\">0.5f<\/span>, <span style=\"color: #666666;\">0.5f<\/span>)\n    .build()<\/b>\n<span style=\"color: green; font-weight: bold;\">val<\/span> editedMediaItem =\n  EditedMediaItem.Builder(mediaItem)\n    <b>.setEffects(\n      <span style=\"color: #408080; font-style: italic;\">\/* audio *\/<\/span> Effects(emptyList(), \n      <span style=\"color: #408080; font-style: italic;\">\/* video *\/<\/span> listOf(scaleEffect))<\/b>\n    )\n    .build()\n<\/pre>\n<\/div>\n<p>An FFmpeg command could look like this:<\/p>\n<p><!--Unset--><\/p>\n<div style=\"background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;\">\n<pre style=\"line-height: 125%; margin: 0px;\">$ ffmpeg <span style=\"color: #666666;\">-<\/span>i <span style=\"color: #19177c;\">$inputVideoPath<\/span> <b><span style=\"color: #666666;\">-<\/span>filter<span style=\"color: #666666;\">:<\/span>v scale<span style=\"color: #666666;\">=<\/span>w<span style=\"color: #666666;\">=<\/span>trunc(iw<span style=\"color: #666666;\">\/4<\/span>)<span style=\"color: #666666;\">*2:<\/span>h<span style=\"color: #666666;\">=<\/span>trunc(ih<span style=\"color: #666666;\">\/4<\/span>)<span style=\"color: #666666;\">*2<\/span><\/b> <span style=\"color: #19177c;\">$outputFilePath<\/span>\n<\/pre>\n<\/div>\n<p>Of course, you can also combine these operations to apply multiple edits on the same video, but hopefully these examples serve to demonstrate that the Transformer APIs make configuring these edits simple.<\/p>\n<h2><span style=\"font-size: x-large;\">Transformer API Performance results<\/span><\/h2>\n<p>Here are some benchmarking measurements for each of the 4 operations taken with the Stopwatch API, running on a Pixel 9 Pro XL device:<\/p>\n<p><i>(Note that performance for operations like these can depend on a variety of reasons, such as the current load the device is under, so the numbers below should be taken as rough estimates.)<\/i><\/p>\n<blockquote>\n<p><b>Input video format:<\/b> <a href=\"https:\/\/storage.googleapis.com\/exoplayer-test-media-1\/mp4\/android-screens-10s.mp4\" target=\"_blank\" rel=\"noopener\">10s 720p H264 video with AAC audio<\/a><\/p>\n<ul>\n<li><b>Transcoding<\/b> to H265 video and AAC audio: ~1300ms<\/li>\n<li><b>Trimming<\/b> video to 00:03-00:08: ~2300ms<\/li>\n<li><b>Muting<\/b> audio: ~200ms<\/li>\n<li><b>Resizing<\/b> video to half height and width: ~1200ms<\/li>\n<\/ul>\n<p><b>Input video format:<\/b> <a href=\"https:\/\/html5demos.com\/assets\/dizzy.webm\" target=\"_blank\" rel=\"noopener\">25s 360p VP8 video with Vorbis audio<\/a><\/p>\n<ul>\n<li><b>Transcoding<\/b> to H265 video and AAC audio: ~3400ms<\/li>\n<li><b>Trimming<\/b> video to 00:03-00:08: ~1700ms<\/li>\n<li><b>Muting<\/b> audio: ~1600ms<\/li>\n<li><b>Resizing<\/b> video to half height and width: ~4800ms<\/li>\n<\/ul>\n<p><b>Input video format:<\/b> <a href=\"https:\/\/storage.googleapis.com\/exoplayer-test-media-1\/mp4\/8k24fps_4s.mp4\" target=\"_blank\" rel=\"noopener\">4s 8k H265 video with AAC audio<\/a><\/p>\n<ul>\n<li><b>Transcoding<\/b> to H265 video and AAC audio: ~2300ms<\/li>\n<li><b>Trimming<\/b> video to 00:03-00:08: ~1800ms<\/li>\n<li><b>Muting<\/b> audio: ~2000ms<\/li>\n<li><b>Resizing<\/b> video to half height and width: ~3700ms<\/li>\n<\/ul>\n<\/blockquote>\n<p>One technique Transformer uses to speed up editing operations is by prioritizing <i>transmuxing<\/i> for basic video edits where possible. <b>Transmuxing<\/b> refers to the process of repackaging video streams without re-encoding, which ensures high-quality output and significantly faster processing times.<\/p>\n<p>When not possible, Transformer falls back to transcoding, a process that involves first decoding video samples into raw data, then re-encoding them for storage in a new container. Here are some of these differences:<\/p>\n<h3><span style=\"font-size: large;\">Transmuxing<\/span><\/h3>\n<ul>\n<ul>\n<li>Transformer\u2019s preferred approach when possible &#8211; a quick transformation that preserves elementary streams.<\/li>\n<li>Only applicable to basic operations, such as rotating, trimming, or container conversion.<\/li>\n<li>No quality loss or bitrate change.<\/li>\n<\/ul>\n<\/ul>\n<p><image><\/p>\n<div style=\"text-align: center;\"><img decoding=\"async\" alt=\"Transmux\" border=\"0\" height=\"270\" id=\"imgCaption\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhxEs9EHg4t55AflszVIYehD8KQlxwybUsBxnxeJSTtvRf3zNaJaCOUi8dHnk9AeFskl2dtrzky6U95sXC2iRXWs7Poj63ftEOHv3ZwpfTJfh5iP5N-DINuq8FB0lbZPA4x9XzqBeCgXXrmmW3I6PSPfRn2g0fk4dHIzKLd5JUiMJVK5-IVJcRh3AN1XKg\/w640-h270\/Transmux-Jetpack-Media3-Transformer.png\" width=\"75%\"\/><\/div>\n<p><\/image><\/p>\n<h3><span style=\"font-size: large;\">Transcoding<\/span><\/h3>\n<ul>\n<ul>\n<li>Transformer&#8217;s fallback approach in cases when Transmuxing isn&#8217;t possible &#8211; Involves decoding and re-encoding elementary streams.<\/li>\n<li>More extensive modifications to the input video are possible.<\/li>\n<li>Loss in quality due to re-encoding, but can achieve a desired bitrate target.<\/li>\n<\/ul>\n<\/ul>\n<p><image><\/p>\n<div style=\"text-align: center;\"><img decoding=\"async\" alt=\"Transcode\" border=\"0\" height=\"506\" id=\"imgCaption\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEg6-v9kxnkd__no1qV3cklVNvDPoYZCCrD6PTYyHSMUtRBhg-FI0SvfZ2G0dlJHyKZtAzjbcMO43uQWuY2SDO9_gN_RhKDDjvxgiLcDt8Dsj2W0el759D8kD_bqy0TXX-Ty9TGkBmurJgvhI_KB2qCR6fX-9P9gi_eS1kmTsjxh0f8ZzLuRBajHmzq3Wxk\/w640-h506\/Transcoding-jetpack-media3-processing.png\" width=\"75%\"\/><\/div>\n<p><\/image><\/p>\n<p>We are continuously implementing further optimizations, such as the recently introduced <span style=\"font-family: courier;\"><a href=\"https:\/\/developer.android.com\/reference\/androidx\/media3\/transformer\/Transformer.Builder#experimentalSetTrimOptimizationEnabled%28boolean%29\" target=\"_blank\" rel=\"noopener\">experimentalSetTrimOptimizationEnabled<\/a><\/span> setting that we used in the Trimming example above.<\/p>\n<p>A trim is usually performed by re-encoding all the samples in the file, but since encoded media samples are stored chronologically in their container, we can improve efficiency by only re-encoding the <i>group of pictures<\/i> (GOP) between the start point of the trim and the first keyframes at\/after the start point, then stream-copying the rest.<\/p>\n<p>Since we only decode and encode a fixed portion of any file, the encoding latency is roughly constant, regardless of what the input video duration is. For long videos, this improved latency is dramatic. The optimization relies on being able to stitch part of the input file with newly-encoded output, which means that the encoder&#8217;s output format and the input format must be compatible.<\/p>\n<p>If the optimization fails, Transformer automatically falls back to normal export.<\/p>\n<h3>What\u2019s next?<\/h3>\n<p>As part of Media3, Transformer is a native solution with low integration complexity, is tested on and ensures compatibility with a wide variety of devices, and is customizable to fit your specific needs.<\/p>\n<p>To dive deeper, you can explore <a href=\"https:\/\/developer.android.com\/media\/media3\/transformer\" target=\"_blank\" rel=\"noopener\">Media3 Transformer documentation<\/a>, run our <a href=\"https:\/\/github.com\/androidx\/media\/tree\/release\/demos\/transformer\" target=\"_blank\" rel=\"noopener\">sample apps<\/a>, or learn how to <a href=\"https:\/\/www.youtube.com\/watch?v=7vmiYP4vNUE\" target=\"_blank\" rel=\"noopener\">complement your media editing pipeline with Jetpack Media3<\/a>. We\u2019ve already seen <a href=\"https:\/\/www.youtube.com\/watch?v=nWXmrY8J_nY&amp;list=PLWz5rJ2EKKc8EtnBH3NwEIbPJaawDjNHv\" target=\"_blank\" rel=\"noopener\">app developers benefit greatly from adopting Transformer<\/a>, so we encourage you to try them out yourself to streamline your media editing workflows and enhance your app\u2019s performance!<\/p>\n<\/div>\n<p>[ad_2]<br \/>\n<br \/><a href=\"http:\/\/android-developers.googleblog.com\/2025\/03\/media-processing-performance-jetpack-media3-transformer.html\">Source link <\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>[ad_1] Posted by Nevin Mital \u2013 Developer Relations Engineer, and Kristina Simakova \u2013 Engineering Manager Android users have demonstrated an increasing desire to create, personalize,<\/p>\n","protected":false},"author":1,"featured_media":272059,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[146],"tags":[],"_links":{"self":[{"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/posts\/272058"}],"collection":[{"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/comments?post=272058"}],"version-history":[{"count":0,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/posts\/272058\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/media\/272059"}],"wp:attachment":[{"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/media?parent=272058"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/categories?post=272058"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/tags?post=272058"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}