2012-06-28 15 views
8

por lo que hacen en mi guión:Python acceso a los datos en JSON objeto

import json 
info = json.loads(get_info()) 
print info 

que da salida:

[email protected]:~/projects/hello-python$ python main.py 
{ 
    "streams": [ 
     { 
      "index": 0, 
      "codec_name": "mpeg2video", 
      "codec_long_name": "MPEG-2 video", 
      "codec_type": "video", 
      "codec_time_base": "1001/48000", 
      "codec_tag_string": "[0][0][0][0]", 
      "codec_tag": "0x0000", 
      "width": 1920, 
      "height": 1080, 
      "has_b_frames": 1, 
      "sample_aspect_ratio": "1:1", 
      "display_aspect_ratio": "16:9", 
      "pix_fmt": "yuv422p", 
      "level": 2, 
      "timecode": "00:59:59:00", 
      "id": "0x1e0", 
      "r_frame_rate": "24000/1001", 
      "avg_frame_rate": "10000/417", 
      "time_base": "1/90000", 
      "start_time": "0.945411" 
     }, 
     { 
      "index": 1, 
      "codec_name": "pcm_dvd", 
      "codec_long_name": "PCM signed 20|24-bit big-endian", 
      "codec_type": "audio", 
      "codec_time_base": "1/48000", 
      "codec_tag_string": "[0][0][0][0]", 
      "codec_tag": "0x0000", 
      "sample_fmt": "s32", 
      "sample_rate": "48000", 
      "channels": 2, 
      "bits_per_sample": 0, 
      "id": "0xa0", 
      "r_frame_rate": "0/0", 
      "avg_frame_rate": "0/0", 
      "time_base": "1/90000", 
      "start_time": "0.945411", 
      "duration": "600.595000" 
     } 
    ], 
    "format": { 
     "filename": "/home/richard/projects/hello-python/tests/test_1.mpg", 
     "nb_streams": 2, 
     "format_name": "mpeg", 
     "format_long_name": "MPEG-PS format", 
     "start_time": "0.945411", 
     "duration": "600.595000", 
     "size": "4033241092", 
     "bit_rate": "53723272" 
    } 
} 

cómo puedo acceder a los arroyos o formato y, a continuación propiedades dentro de ellos? Por ejemplo, ¿cómo obtener codec_long_name de la segunda transmisión o cómo obtener la duración del formato?

me trataron:

print info[0] 

que da salida:

[email protected]:~/projects/hello-python$ python main.py 
{ 

Si hago repr impresión (info), me sale:

[email protected]:~/projects/hello-python$ python main.py 
'{\n "streams": [\n  {\n   "index": 0,\n   "codec_name": "mpeg2video",\n   "codec_long_name": "MPEG-2 video",\n   "codec_type": "video",\n   "codec_time_base": "1001/48000",\n   "codec_tag_string": "[0][0][0][0]",\n   "codec_tag": "0x0000",\n   "width": 1920,\n   "height": 1080,\n   "has_b_frames": 1,\n   "sample_aspect_ratio": "1:1",\n   "display_aspect_ratio": "16:9",\n   "pix_fmt": "yuv422p",\n   "level": 2,\n   "timecode": "00:59:59:00",\n   "id": "0x1e0",\n   "r_frame_rate": "24000/1001",\n   "avg_frame_rate": "10000/417",\n   "time_base": "1/90000",\n   "start_time": "0.945411"\n  },\n  {\n   "index": 1,\n   "codec_name": "pcm_dvd",\n   "codec_long_name": "PCM signed 20|24-bit big-endian",\n   "codec_type": "audio",\n   "codec_time_base": "1/48000",\n   "codec_tag_string": "[0][0][0][0]",\n   "codec_tag": "0x0000",\n   "sample_fmt": "s32",\n   "sample_rate": "48000",\n   "channels": 2,\n   "bits_per_sample": 0,\n   "id": "0xa0",\n   "r_frame_rate": "0/0",\n   "avg_frame_rate": "0/0",\n   "time_base": "1/90000",\n   "start_time": "0.945411",\n   "duration": "600.595000"\n  }\n ],\n "format": {\n  "filename": "/home/richard/projects/hello-python/tests/test_1.mpg",\n  "nb_streams": 2,\n  "format_name": "mpeg",\n  "format_long_name": "MPEG-PS format",\n  "start_time": "0.945411",\n  "duration": "600.595000",\n  "size": "4033241092",\n  "bit_rate": "53723272"\n }\n}\n' 

La forma en que estoy recibiendo el JSON la cadena está bu ejecutando este comando:

ffmpeg_command = "ffprobe -v quiet -print_format json -show_format -show_streams %s" % self.absolute_path 
return subprocess.check_output(ffmpeg_command, shell=True) 

Respuesta

10

El JSON se codificó dos veces, y el resultado de json.loads es una cadena. Las cadenas en python son secuencias, por lo que el primer carácter es un {.

decodificar el elemento de nuevo:

info = json.loads(json.loads(get_info())) 

Ahora su salida main.py debe verse como:

>>> result = json.loads(output) 
>>> print result 
{u'streams': [{u'pix_fmt': u'yuv422p', u'index': 0, u'start_time': u'0.945411', u'codec_tag': u'0x0000', u'sample_aspect_ratio': u'1:1', u'level': 2, u'r_frame_rate': u'24000/1001', u'id': u'0x1e0', u'time_base': u'1/90000', u'codec_tag_string': u'[0][0][0][0]', u'codec_type': u'video', u'has_b_frames': 1, u'width': 1920, u'codec_long_name': u'MPEG-2 video', u'display_aspect_ratio': u'16:9', u'codec_name': u'mpeg2video', u'timecode': u'00:59:59:00', u'height': 1080, u'codec_time_base': u'1001/48000', u'avg_frame_rate': u'10000/417'}, {u'index': 1, u'sample_fmt': u's32', u'codec_tag': u'0x0000', u'bits_per_sample': 0, u'r_frame_rate': u'0/0', u'start_time': u'0.945411', u'time_base': u'1/90000', u'codec_tag_string': u'[0][0][0][0]', u'codec_type': u'audio', u'channels': 2, u'duration': u'600.595000', u'codec_long_name': u'PCM signed 20|24-bit big-endian', u'codec_name': u'pcm_dvd', u'id': u'0xa0', u'sample_rate': u'48000', u'codec_time_base': u'1/48000', u'avg_frame_rate': u'0/0'}], u'format': {u'nb_streams': 2, u'start_time': u'0.945411', u'format_long_name': u'MPEG-PS format', u'format_name': u'mpeg', u'filename': u'/home/richard/projects/hello-python/tests/test_1.mpg', u'bit_rate': u'53723272', u'duration': u'600.595000', u'size': u'4033241092'}} 

y se puede acceder a los arroyos y parámetros de formato por su nombre:

>>> result['streams'] 
[{u'pix_fmt': u'yuv422p', u'index': 0, u'start_time': u'0.945411', u'codec_tag': u'0x0000', u'sample_aspect_ratio': u'1:1', u'level': 2, u'r_frame_rate': u'24000/1001', u'id': u'0x1e0', u'time_base': u'1/90000', u'codec_tag_string': u'[0][0][0][0]', u'codec_type': u'video', u'has_b_frames': 1, u'width': 1920, u'codec_long_name': u'MPEG-2 video', u'display_aspect_ratio': u'16:9', u'codec_name': u'mpeg2video', u'timecode': u'00:59:59:00', u'height': 1080, u'codec_time_base': u'1001/48000', u'avg_frame_rate': u'10000/417'}, {u'index': 1, u'sample_fmt': u's32', u'codec_tag': u'0x0000', u'bits_per_sample': 0, u'r_frame_rate': u'0/0', u'start_time': u'0.945411', u'time_base': u'1/90000', u'codec_tag_string': u'[0][0][0][0]', u'codec_type': u'audio', u'channels': 2, u'duration': u'600.595000', u'codec_long_name': u'PCM signed 20|24-bit big-endian', u'codec_name': u'pcm_dvd', u'id': u'0xa0', u'sample_rate': u'48000', u'codec_time_base': u'1/48000', u'avg_frame_rate': u'0/0'}] 

Consejo profesional: utilice el pprint module para formatear estructuras de python muy bien:

>>> from pprint import pprint 
>>> print pprint(result) 
>>> pprint(result) 
{u'format': {u'bit_rate': u'53723272', 
      u'duration': u'600.595000', 
      u'filename': u'/home/richard/projects/hello-python/tests/test_1.mpg', 
      u'format_long_name': u'MPEG-PS format', 
      u'format_name': u'mpeg', 
      u'nb_streams': 2, 
      u'size': u'4033241092', 
      u'start_time': u'0.945411'}, 
u'streams': [{u'avg_frame_rate': u'10000/417', 
       u'codec_long_name': u'MPEG-2 video', 
       u'codec_name': u'mpeg2video', 
       u'codec_tag': u'0x0000', 
       u'codec_tag_string': u'[0][0][0][0]', 
       u'codec_time_base': u'1001/48000', 
       u'codec_type': u'video', 
       u'display_aspect_ratio': u'16:9', 
       u'has_b_frames': 1, 
       u'height': 1080, 
       u'id': u'0x1e0', 
       u'index': 0, 
       u'level': 2, 
       u'pix_fmt': u'yuv422p', 
       u'r_frame_rate': u'24000/1001', 
       u'sample_aspect_ratio': u'1:1', 
       u'start_time': u'0.945411', 
       u'time_base': u'1/90000', 
       u'timecode': u'00:59:59:00', 
       u'width': 1920}, 
       {u'avg_frame_rate': u'0/0', 
       u'bits_per_sample': 0, 
       u'channels': 2, 
       u'codec_long_name': u'PCM signed 20|24-bit big-endian', 
       u'codec_name': u'pcm_dvd', 
       u'codec_tag': u'0x0000', 
       u'codec_tag_string': u'[0][0][0][0]', 
       u'codec_time_base': u'1/48000', 
       u'codec_type': u'audio', 
       u'duration': u'600.595000', 
       u'id': u'0xa0', 
       u'index': 1, 
       u'r_frame_rate': u'0/0', 
       u'sample_fmt': u's32', 
       u'sample_rate': u'48000', 
       u'start_time': u'0.945411', 
       u'time_base': u'1/90000'}]} 
+0

En ese caso, me sale: TypeError: se esperaba cadena o tampón –

+0

entonces lo que se el resultado de 'print type (info), repr (info)' (sin decodificación doble)? –

+0

Sin la decodificación dobule es:

0

Trate

from StringIO import StringIO 
io = StringIO(get_info()) 
json.load(io) 
1

Para imprimir codec_long_name y duration de la segunda corriente haga lo siguiente:

details = subprocess.check_output(["C:/FFmpeg/bin/ffprobe.exe", 
    "-loglevel", "quiet", "-print_format", "json", "-show_streams", 
    file_path]) 
info = json.loads(details) 
print info['streams'][1]['codec_long_name'], info['streams'][1]['duration'] 
Cuestiones relacionadas