Skip to content

Instantly share code, notes, and snippets.

@movalex
Last active January 10, 2024 18:57
Show Gist options
  • Save movalex/88a419b574b8f4adccb668b1b7743840 to your computer and use it in GitHub Desktop.
Save movalex/88a419b574b8f4adccb668b1b7743840 to your computer and use it in GitHub Desktop.
Power Query Youtube API parse Songs
let
Source = Excel.CurrentWorkbook(){[Name="tblVideoURLS"]}[Content],
AddVideoDetails = Table.AddColumn(
Source,
"VideoDetails",
each fnGetVideoDetails([URL])
),
AddTitle = Table.ExpandRecordColumn(
AddVideoDetails,
"VideoDetails",
{"Title", "Duration", "IsHD" },
{"Title", "Duration", "IsHD" }
),
ConvertedDuration = Table.TransformColumns(AddTitle, {"Duration", each ParseDuration(_), type time}),
#"Split Column by Delimiter" = Table.SplitColumn(ConvertedDuration, "Title", Splitter.SplitTextByEachDelimiter({"<meta name=""description"""}, QuoteStyle.None, true), {"Title.1", "Title.2"}),
#"Changed Type" = Table.TransformColumnTypes(#"Split Column by Delimiter",{{"Title.1", type text}, {"Title.2", type text}}),
#"Renamed Columns" = Table.RenameColumns(#"Changed Type",{{"Title.1", "Title"}}),
#"Removed Columns" = Table.RemoveColumns(#"Renamed Columns",{"Title.2"}),
#"Removed Errors" = Table.RemoveRowsWithErrors(#"Removed Columns", {"Title"}),
#"Split Column by Delimiter1" = Table.SplitColumn(#"Removed Errors", "Title", Splitter.SplitTextByEachDelimiter({" ("}, QuoteStyle.Csv, true), {"Title.1", "Title.2"}),
#"Changed Type1" = Table.TransformColumnTypes(#"Split Column by Delimiter1",{{"Title.1", type text}, {"Title.2", type text}}),
#"Removed Columns1" = Table.RemoveColumns(#"Changed Type1",{"Title.2"}),
#"SplitTitle" = Table.SplitColumn(#"Removed Columns1", "Title.1", Splitter.SplitTextByAnyDelimiter({" – "," — "," - "," . ", ": ", " | "}, QuoteStyle.Csv), {"Author", "Song"}),
#"Uppercased Text" = Table.TransformColumns(SplitTitle,{{"Song", Text.Upper, type text}}),
#"Replaced Value" = Table.ReplaceValue(#"Uppercased Text","&amp;","&",Replacer.ReplaceText,{"Author"}),
#"Remove Brackets" = Table.SplitColumn(#"Replaced Value", "Song", Splitter.SplitTextByEachDelimiter({"["}, QuoteStyle.None, true), {"Song", "Song.Remove"}),
#"Removed Brackets" = Table.RemoveColumns(#"Remove Brackets",{"Song.Remove"}),
#"Add Title" = Table.AddColumn(#"Removed Brackets", "title", each [Author]&" - "& [Song])
in
#"Add Title"
// fnGetVideoDetails
let
fnGetVideoDetails = (URL as text) as record =>
let
// Extract Video ID from the URL in one line
VideoID = if Text.Contains(URL, "&") then Text.BetweenDelimiters(URL, "v=", "&") else Text.AfterDelimiter(URL, "v="),
ApiKey = "YOUTUBE_API", // Replace with your YouTube API Key
ApiUrl = "https://www.googleapis.com/youtube/v3/videos?id=" & VideoID & "&part=snippet,contentDetails&key=" & ApiKey,
jsonResponse = Web.Contents(ApiUrl),
parsedJson = Json.Document(jsonResponse),
videoTitle = parsedJson[items]{0}[snippet][title],
videoDuration = parsedJson[items]{0}[contentDetails][duration],
videoDefinition = parsedJson[items]{0}[contentDetails][definition],
isHD = videoDefinition = "hd",
Result = [Title = videoTitle, Duration = videoDuration, IsHD = isHD]
in
Result
in
fnGetVideoDetails
// ParseDuration
let
ParseDuration = (duration as text) as nullable time =>
let
minutesText = Text.BetweenDelimiters(duration, "PT", "M"),
secondsText = Text.BetweenDelimiters(duration, "M", "S"),
minutes = if minutesText <> "" then Number.FromText(minutesText) else 0,
seconds = if secondsText <> "" then Number.FromText(secondsText) else 0,
time = #time(0, minutes, seconds)
in
time
in
ParseDuration
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment