├── .idea ├── .name ├── dictionaries │ └── twotrees.xml ├── vcs.xml ├── modules.xml ├── Sony-Walkman-Sorter.iml ├── misc.xml └── workspace.xml ├── requirements.txt ├── 1.jpg ├── 2.jpg ├── 3.jpg ├── README.md ├── SortFilesForce.py └── SortFiles.py /.idea/.name: -------------------------------------------------------------------------------- 1 | Sony-Walkman-Sorter -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | mutagen 2 | pypinyin 3 | -------------------------------------------------------------------------------- /1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/twotreeszf/Sony-Walkman-Sorter/HEAD/1.jpg -------------------------------------------------------------------------------- /2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/twotreeszf/Sony-Walkman-Sorter/HEAD/2.jpg -------------------------------------------------------------------------------- /3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/twotreeszf/Sony-Walkman-Sorter/HEAD/3.jpg -------------------------------------------------------------------------------- /.idea/dictionaries/twotrees.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/Sony-Walkman-Sorter.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | Buildout 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Sony-Walkman-Sorter 2 | ## 背景 3 | ### Sony Walkman NW-A15/25 NW-ZX1/2/100、iBasso DX50/80/90 等HiFi播放器不能按照中文歌手、专辑、歌名进行排序显示,中文都被归到了etc下,导致查找中文歌曲和歌手非常麻烦 4 | ### 我综合了以下资料,搞定了这个问题,经测试可实现中文歌曲按照歌手、专辑、歌名准确排序,而且中文信息前并不会出现可见字母前缀! 5 | - [walkman 自动添加中文排序信息的脚本](http://tieba.baidu.com/p/3436217262) 6 | - [SONY Walkman NWZ-A17 不專業的開箱文](http://blog.xuite.net/terry30173/2dx/275537359-SONY+Walkman+NWZ-A17+%E4%B8%8D%E5%B0%88%E6%A5%AD%E7%9A%84%E9%96%8B%E7%AE%B1%E6%96%87) 7 | - [Walkman-sort-by-title](https://github.com/agmcs/Walkman-sort-by-title/blob/master/TitleSort2.0.py) 8 | - [https://mutagen.readthedocs.org/en/latest/man/index.html]() 9 | - [http://mutagen.readthedocs.org/en/latest/api/mp4.html]() 10 | - [Tag field mappings](http://help.mp3tag.de/main_tags.html) 11 | 12 | ## 支持系统 13 | 理论上支持Windows/Mac/Linux系统,只要有Python即可,个人仅在Mac上测试 14 | ## 支持机型 15 | 理论上支持所有非智能Walkman,个人仅在ZX100上测试 16 | 17 | ## 使用方法 18 | 1. build目录下有打包好的处理工具。对应的操作系统下有SortFilesiBasso和SortFilesSony两个排序工具, 19 | SortFilesiBasso用于DX50/80/90/100等不支持sort tags的机型,排序后歌名、歌手、专辑名称前面会出现字母前缀 20 | SortFilesSony用于ZX1/2/100 A15/25等支持支持sort tags的机型,排序后不会出现字母前缀 21 | 2. 将对应的工具拷贝到音乐文件所在目录,直接双击或者在命令行之行即可。会自动跳过已处理过的和英文歌曲,所以下次增加了音频只需要再运行一次即可。Windows用户需要先安装vcredist_x86.exe 22 | 23 | 作者:twotrees 24 | Email:twotrees.zf@gmail.com 25 | QQ:329292657 26 | 27 | ![](/1.jpg) 28 | ![](/2.jpg) 29 | ![](/3.jpg) 30 | 31 | -------------------------------------------------------------------------------- /SortFilesForce.py: -------------------------------------------------------------------------------- 1 | #coding: utf-8 2 | import sys 3 | reload(sys) 4 | sys.setdefaultencoding('utf-8') 5 | 6 | import os 7 | from os import path 8 | 9 | from mutagen.easyid3 import EasyID3 10 | EasyID3.RegisterTextKey('ALBUMARTIST', 'TPE2') 11 | EasyID3.RegisterTextKey('ALBUMARTISTSORT', 'TSO2') 12 | 13 | from mutagen.mp3 import EasyMP3 as MP3 14 | from mutagen.easymp4 import EasyMP4 as MP4 15 | from mutagen.flac import FLAC 16 | 17 | from pypinyin import lazy_pinyin 18 | 19 | def beginWithCJK(str): 20 | if u'\u4e00' <= str[0] <= u'\u9fff': 21 | return True 22 | else: 23 | return False 24 | 25 | def CJKFirstLetters(str): 26 | pinyins = lazy_pinyin(str) 27 | firstLetters = '' 28 | for pinyin in pinyins: 29 | firstLetters += pinyin[0] 30 | 31 | return firstLetters 32 | 33 | def checkTagMakeSort(path, meta, tagName): 34 | value = meta.get(tagName) 35 | if value and len(value) and value[0] != '': 36 | value = value[0] 37 | if not beginWithCJK(value): 38 | return False 39 | else: 40 | firstLetters = CJKFirstLetters(value).upper() 41 | newValue = firstLetters[0:3] + '^' + value 42 | meta[tagName] = newValue 43 | print('[info] {0}: processed [{1}] is \"{2}\"'.format(path, tagName, newValue)) 44 | return True 45 | 46 | return False 47 | 48 | def setSortTags(path): 49 | ext = os.path.splitext(path)[1].lower() 50 | meta = None 51 | 52 | try: 53 | if ext == '.mp3': 54 | meta = MP3(path) 55 | elif ext == '.m4a': 56 | meta = MP4(path) 57 | elif ext == '.flac': 58 | meta = FLAC(path) 59 | else: 60 | return 61 | except: 62 | pass 63 | 64 | if meta: 65 | tagsToProcess = ('ALBUM', 'ALBUMARTIST', 'ARTIST', 'TITLE') 66 | save = False 67 | try: 68 | for tag in tagsToProcess: 69 | processed = checkTagMakeSort(path, meta, tag) 70 | if (processed): 71 | save = True 72 | if save: 73 | meta.save() 74 | except: 75 | pass 76 | 77 | def processFilesInFolder(folder): 78 | dirlist = os.listdir(folder) 79 | for x in dirlist: 80 | abspath = path.join(folder, x) 81 | if(path.isfile(abspath)): 82 | setSortTags(abspath) 83 | elif (path.isdir(abspath)): 84 | processFilesInFolder(abspath) 85 | 86 | if __name__ == '__main__': 87 | message = ''' 88 | Walkman file sorter by twotrees, Email:twotrees.zf@gmail.com, QQ:329292657 89 | 90 | Usage: 91 | 92 | Process in current folder: 93 | ./SortFiles 94 | 95 | Process in specified folder: 96 | ./SortFiles [folder_path] 97 | 98 | ''' 99 | print(message) 100 | 101 | folder = None 102 | if len(sys.argv) < 2 : 103 | print('[info] no folder path specified, process current folder') 104 | folder = os.getcwd() 105 | else: 106 | folder = sys.argv[1] 107 | if not path.isdir(folder): 108 | print('[error] target folder not exist') 109 | folder = None 110 | 111 | if (folder): 112 | print('[info] process folder [{0}]'.format(folder)) 113 | processFilesInFolder(folder) -------------------------------------------------------------------------------- /SortFiles.py: -------------------------------------------------------------------------------- 1 | #coding: utf-8 2 | import sys 3 | reload(sys) 4 | sys.setdefaultencoding('utf-8') 5 | 6 | import os 7 | from os import path 8 | 9 | from mutagen.easyid3 import EasyID3 10 | EasyID3.RegisterTextKey('ALBUMARTIST', 'TPE2') 11 | EasyID3.RegisterTextKey('ALBUMARTISTSORT', 'TSO2') 12 | 13 | from mutagen.mp3 import EasyMP3 as MP3 14 | from mutagen.easymp4 import EasyMP4 as MP4 15 | from mutagen.flac import FLAC 16 | 17 | from pypinyin import lazy_pinyin 18 | 19 | def beginWithCJK(str): 20 | if u'\u4e00' <= str[0] <= u'\u9fff': 21 | return True 22 | else: 23 | return False 24 | 25 | def CJKFirstLetters(str): 26 | pinyins = lazy_pinyin(str) 27 | firstLetters = '' 28 | for pinyin in pinyins: 29 | firstLetters += pinyin[0] 30 | 31 | return firstLetters 32 | 33 | def checkTagMakeSort(path, meta, tagName): 34 | sortKey = tagName + 'SORT' 35 | 36 | tagSort = meta.get(sortKey) 37 | if tagSort and len(tagSort) and tagSort[0] != '': 38 | tagSort = tagSort[0] 39 | if not beginWithCJK(tagSort): 40 | return False 41 | 42 | tag = meta.get(tagName) 43 | if (not tag) or (not len(tag)) or (tag[0] == ''): 44 | return False 45 | else: 46 | tag = tag[0] 47 | if not beginWithCJK(tag): 48 | return False 49 | else: 50 | firstLetters = CJKFirstLetters(tag) 51 | meta[sortKey] = firstLetters 52 | print('[info] {0}: processed [{1}] is \"{2}\"'.format(path, sortKey, firstLetters)) 53 | return True 54 | 55 | def setSortTags(path): 56 | ext = os.path.splitext(path)[1].lower() 57 | meta = None 58 | 59 | try: 60 | if ext == '.mp3': 61 | meta = MP3(path) 62 | elif ext == '.m4a': 63 | meta = MP4(path) 64 | elif ext == '.flac': 65 | meta = FLAC(path) 66 | else: 67 | return 68 | except: 69 | pass 70 | 71 | if meta: 72 | tagsToProcess = ('ALBUM', 'ALBUMARTIST', 'ARTIST', 'TITLE') 73 | save = False 74 | try: 75 | for tag in tagsToProcess: 76 | processed = checkTagMakeSort(path, meta, tag) 77 | if (processed): 78 | save = True 79 | if save: 80 | meta.save() 81 | except: 82 | pass 83 | 84 | def processFilesInFolder(folder): 85 | dirlist = os.listdir(folder) 86 | for x in dirlist: 87 | abspath = path.join(folder, x) 88 | if(path.isfile(abspath)): 89 | setSortTags(abspath) 90 | elif (path.isdir(abspath)): 91 | processFilesInFolder(abspath) 92 | 93 | if __name__ == '__main__': 94 | message = ''' 95 | Walkman file sorter by twotrees, Email:twotrees.zf@gmail.com, QQ:329292657 96 | 97 | Usage: 98 | 99 | Process in current folder: 100 | ./SortFiles 101 | 102 | Process in specified folder: 103 | ./SortFiles [folder_path] 104 | 105 | ''' 106 | print(message) 107 | 108 | folder = None 109 | if len(sys.argv) < 2 : 110 | print('[info] no folder path specified, process current folder') 111 | folder = folder = os.getcwd() 112 | else: 113 | folder = sys.argv[1] 114 | if not path.isdir(folder): 115 | print('[error] target folder not exist') 116 | folder = None 117 | 118 | if (folder): 119 | print('[info] process folder [{0}]'.format(folder)) 120 | processFilesInFolder(folder) -------------------------------------------------------------------------------- /.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 18 | 19 | 20 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 93 | 94 | 100 | 101 | 102 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 139 | 140 | 141 | 142 | 145 | 146 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 183 | 184 | 200 | 201 | 211 | 212 | 213 | 214 | 215 | 231 | 232 | 243 | 244 | 262 | 263 | 281 | 282 | 302 | 303 | 324 | 325 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 1461674957074 370 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 404 | 407 | 408 | 409 | 411 | 412 | 413 | 414 | 415 | file://$PROJECT_DIR$/SortFiles.py 416 | 108 417 | 419 | 420 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | 730 | 731 | 732 | 733 | 734 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 | 753 | 754 | 755 | 756 | 757 | 758 | 759 | 760 | 761 | 762 | 763 | 764 | 765 | 766 | 767 | 768 | 769 | 770 | 771 | 772 | 773 | 774 | 775 | 776 | 777 | 778 | 779 | 780 | 781 | 782 | 783 | 784 | 785 | 786 | 787 | 788 | 789 | 790 | 791 | 792 | 793 | 794 | 795 | 796 | 797 | 798 | 799 | 800 | 801 | 802 | 803 | 804 | 805 | 806 | 807 | 808 | 809 | 810 | 811 | 812 | 813 | 814 | 815 | 816 | 817 | 818 | 819 | 820 | 821 | 822 | 823 | 824 | 825 | 826 | 827 | 828 | 829 | 830 | 831 | 832 | --------------------------------------------------------------------------------