コピペ: cueask.pl - cueファイルをもとにMusicBrainzに問い合わせるやつ

よく考えたらそんなソフト必要なかった。

形式
Perl
投稿日時
2017-09-04 00:47
公開期間
無期限
  1. #!/usr/bin/perl
  2. use warnings;
  3. use strict;
  4. use utf8;
  5. use Encode;
  6. use open ":locale";
  7. use LWP::UserAgent;
  8. use XML::LibXML;
  9. my $cuename;
  10. my $cueenc = "";
  11. my $wavor;
  12. my @encops;
  13. for(@ARGV){
  14. if(!length($cueenc) && /^:/){
  15. $cueenc = $_;
  16. }elsif(!defined($cuename)){
  17. $cuename = $_;
  18. }elsif(!defined($wavor)){
  19. $wavor = $_;
  20. }
  21. }
  22. if(!defined($cuename)){
  23. die "give cue";
  24. }
  25. my @tracks;
  26. my $disc = {};
  27. my $pt = $disc;
  28. my $cue;
  29. open($cue, "<$cueenc", $cuename) || die "cue open error";
  30. while(<$cue>){
  31. my @lt;
  32. while(/(?|([^\s"]+)|"((?:[^"]|(?<=(?<!\\)\\)")*)")/g){
  33. push(@lt, $1);
  34. $lt[$#lt] =~ s/\\([\\"])/$1/g;
  35. }
  36. if($lt[0] eq "PERFORMER" || $lt[0] eq "TITLE"){
  37. $pt->{lc($lt[0])} = $lt[1];
  38. }elsif($lt[0] eq "FILE"){
  39. $wavor = $lt[1] if(!defined($wavor));
  40. }elsif($lt[0] eq "INDEX"){
  41. if($lt[2] !~ /^([0-9]{2}):([0-9]{2}):([0-9]{2})$/){
  42. die "index error";
  43. }
  44. my $s = $1 * 60 + $2 + $3 / 75;
  45. if($lt[1] == 0){
  46. $pt->{prgap} = $s;
  47. }elsif($lt[1] == 1){
  48. $pt->{start} = $s;
  49. $pt->{prgap} = $s if(!defined($pt->{prgap}));
  50. }
  51. }elsif($lt[0] eq "TRACK"){
  52. if($tracks[$lt[1]]){
  53. die "track has same number";
  54. }
  55. $pt = {num => 0+$lt[1]};
  56. $tracks[$lt[1] - 1] = $pt;
  57. }
  58. }
  59. if(!defined($wavor)){
  60. die "give audio file";
  61. }
  62. my $probd;
  63. open($probd, "-|", "ffprobe", "-v", "0", "-show_streams", $wavor) || die;
  64. my $d = 1;
  65. my $dflags = 0;
  66. while(<$probd>){
  67. if(/^time_base=([0-9]+)\/([0-9]+)$/){
  68. $d *= $1 / $2;
  69. $dflags |= 1;
  70. }elsif(/^duration_ts=([0-9]+)$/){
  71. $d *= $1;
  72. $dflags |= 2;
  73. }
  74. }
  75. close($probd);
  76. my $sectoffset = 150.5;
  77. my @tocid = (1, int(@tracks), int(75 * $d + $sectoffset));
  78. my $lasp;
  79. for(@tracks){
  80. push(@tocid, int(75 * $_->{prgap} + $sectoffset));
  81. $lasp = $_->{prgap};
  82. }
  83. if($dflags != 3 || $d < $lasp){
  84. my $dlast = $lasp + $lasp / (@tracks - 1);
  85. $tocid[2] = int(75 * $dlast + $sectoffset);
  86. }
  87. my $ua = LWP::UserAgent->new(agent=>"cueask.pl-script/0.1 (by dyknon)");
  88. my $dres = $ua->get("https://musicbrainz.org/ws/2/discid/-?toc=".join("+", @tocid)."&inc=recordings+artists");
  89. if($dres->code != 200){
  90. die "MusicBrainz API call error";
  91. }
  92. my $ddom = XML::LibXML->load_xml(string=>$dres->content);
  93. my $dxc = XML::LibXML::XPathContext->new($ddom);
  94. $dxc->registerNs("m", "http://musicbrainz.org/ns/mmd-2.0#");
  95. my @releases = $dxc->findnodes("/m:metadata/m:release-list/m:release");
  96. if(!@releases){
  97. die "Not found in MusicBrainz Database";
  98. }
  99. print(int(@releases)." releases found.\n");
  100. while(my ($n, $r) = each(@releases)){
  101. print("release: https://musicbrainz.org/release/" . $dxc->findvalue("\@id", $r) . "\n");
  102. print(" title: " . $dxc->findvalue("m:title[1]", $r) . "\n");
  103. my @artists = $dxc->findnodes("m:artist-credit[1]/m:name-credit", $r);
  104. if(@artists){
  105. print(" artist: ");
  106. for(@artists){
  107. print($dxc->findvalue("m:artist/m:name", $_));
  108. print($dxc->findvalue("\@joinphrase", $_));
  109. }
  110. print("\n");
  111. }
  112. my $possort = sub{
  113. my $gpos = sub{
  114. $dxc->findvalue("m:position", shift);
  115. };
  116. sort{$gpos->($a) <=> $gpos->($b)}(@_);
  117. };
  118. my @mediums = $possort->($dxc->findnodes("m:medium-list/m:medium", $r));
  119. for my $m(@mediums){
  120. print(" media " . $dxc->findvalue("m:position", $m)
  121. . "(" . $dxc->findvalue("m:format", $m) . "):\n");
  122. for my $t($dxc->findnodes("m:track-list/m:track", $m)){
  123. print(" track " . $dxc->findvalue("m:number", $t) . ": "
  124. . $dxc->findvalue("m:recording/m:title", $t)
  125. . "\n");
  126. }
  127. }
  128. }
ダウンロード 印刷用表示

このコピペの URL

JavaScript での埋め込み

iframe での埋め込み

元のテキスト