Coverage for pyguymer3/media/return_audio_format.py: 49%

41 statements  

« prev     ^ index     » next       coverage.py v7.9.2, created at 2025-07-08 18:47 +0000

1#!/usr/bin/env python3 

2 

3# Define function ... 

4def return_audio_format( 

5 fname, 

6 /, 

7 *, 

8 cwd = None, 

9 debug = __debug__, 

10 ensureNFC = True, 

11 ffprobePath = None, 

12 playlist = -1, 

13 timeout = 60.0, 

14): 

15 """Return the format of the first audio stream in a media file 

16 

17 This function will return a pretty string of the format of the first audio 

18 stream in a media file. 

19 

20 Parameters 

21 ---------- 

22 fname : str 

23 the media file 

24 cwd : str, optional 

25 the directory to change to before running "ffprobe" 

26 debug : bool, optional 

27 print debug messages 

28 ffprobePath : str, optional 

29 the path to the "ffprobe" binary (if not provided then Python will 

30 attempt to find the binary itself) 

31 playlist : int, optional 

32 for media files containing playlists, specify which playlist wants to be 

33 surveyed 

34 timeout : float, optional 

35 the timeout for any requests/subprocess calls 

36 

37 Returns 

38 ------- 

39 fmt : str 

40 the format as a pretty string 

41 

42 Notes 

43 ----- 

44 Copyright 2017 Thomas Guymer [1]_ 

45 

46 References 

47 ---------- 

48 .. [1] PyGuymer3, https://github.com/Guymer/PyGuymer3 

49 """ 

50 

51 # Import standard modules ... 

52 import shutil 

53 

54 # Import sub-functions ... 

55 from .__ffprobe__ import __ffprobe__ 

56 from .ffprobe import ffprobe 

57 

58 # ************************************************************************** 

59 

60 # Try to find the paths if the user did not provide them ... 

61 if ffprobePath is None: 

62 ffprobePath = shutil.which("ffprobe") 

63 assert ffprobePath is not None, "\"ffprobe\" is not installed" 

64 

65 # ************************************************************************** 

66 

67 # Make sure that this fname/playlist combination is in the global dictionary ... 

68 if fname not in __ffprobe__: 

69 __ffprobe__[fname] = {} 

70 if playlist not in __ffprobe__[fname]: 

71 if debug: 

72 print(f"INFO: Running ffprobe(\"{fname}\", {playlist:d}) ...") 

73 __ffprobe__[fname][playlist] = ffprobe( 

74 fname, 

75 cwd = cwd, 

76 ensureNFC = ensureNFC, 

77 ffprobePath = ffprobePath, 

78 playlist = playlist, 

79 timeout = timeout, 

80 ) 

81 

82 # Loop over streams ... 

83 for stream in __ffprobe__[fname][playlist]["streams"]: 

84 # Skip stream if it is not audio ... 

85 if stream["codec_type"].strip().lower() != "audio": 

86 continue 

87 

88 # Return format ... 

89 if "codec_name" in stream: 

90 match stream["codec_name"]: 

91 case "aac": 

92 return "AAC" 

93 case "adpcm_ima_qt": 

94 return "Adaptive Differential PCM" 

95 case "alac": 

96 return "ALAC" 

97 case "flac": 

98 return "FLAC" 

99 case "mp3": 

100 return "MP3" 

101 case "qdm2": 

102 return "QDesign Music" 

103 case "vorbis": 

104 return "Vorbis" 

105 case "wmapro": 

106 return "WMA 9 Pro" 

107 case "wmav1": 

108 return "WMA 1" 

109 case "wmav2": 

110 return "WMA 2" 

111 case _: 

112 raise ValueError(f'\"codec_name\" is an unexpected value ({repr(stream["codec_name"])})') from None 

113 

114 # Return error ... 

115 return "ERROR"