范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

Android音视频硬解码播放H264

  最近在学习ing,加油 硬件和软件编解码器
  在介绍之前,我们需要知道什么是硬编解码器和软编解码器?
  1.软编解码器 :使用软件本身或使用CPU的方式对原始视频进行编解码。
  优点:兼容性好。.
  缺点:CPU占用率高,app内存占用较高,可能是因为CPU发热导致降频、卡顿、无法流畅录制、播放视频等。
  2.硬编解码器 :使用非CPU编码,如显卡GPU、专用DSP芯片、厂商芯片等。一般编解码算法是固定的,所以采用芯片处理。
  优点:非常快速高效,CPU占用率低,即使长时间录制高清视频,手机也不会发热。
  缺点:但是兼容性不好,经常出现画面不够精细的问题(但是看不出来)。 MediaCodec 硬编解码器
  一般安卓直播采集终端/短视频编辑软件默认使用硬编解码,如果手机不支持软编解码。硬编解码器为王。
  在 Android MediaCodec  类中使用的是编码和解码。MediaCodec  它是什么??MediaCodec  是 Android 音视频编解码类,它通过访问底层codec  来实现编解码的功能,比如需要把摄像头的视频 yuv 数据编码为h264/h265  ,pcm  编码为aac  ,h264/h265  解码等待yuv  ,aac  解码pcm  等待。MediaCodec  是 Android 4.1 API16 引入了,在 Android 5.0 API21 中加入了异步模式。
  MediaCodec Call是系统注册的编解码器,硬件厂商在系统中注册自己的硬编解码器,称为硬编解码器,如果硬件厂商注册软件编解码器,就是软件编解码器。通常不同的硬件制造商是不同的。然后 MediaCodec 负责调用。 获取手机支持的编解码器
  不同的手机支持的编解码器不同,如何获取手机支持的编解码器?如下:     @RequiresApi(Build.VERSION_CODES.LOLLIPOP)     private fun getSupportCodec() {         val list = MediaCodecList(MediaCodecList.REGULAR_CODECS)         val codecs = list.codecInfos         Log.d(TAG, "Decoders:")         for (codec in codecs) {             if (!codec.isEncoder) Log.d(TAG, codec.name)         }         Log.d(TAG, "Encoders:")         for (codec in codecs) {             if (codec.isEncoder) Log.d(TAG, codec.name)         }     }
  输出 2020-12-25 19:16:00.914 13115-13115/com.bj.gxz.h264decoderdemo D/H264: Decoders: 2020-12-25 19:16:00.914 13115-13115/com.bj.gxz.h264decoderdemo D/H264: OMX.google.aac.decoder 2020-12-25 19:16:00.914 13115-13115/com.bj.gxz.h264decoderdemo D/H264: OMX.google.amrnb.decoder 2020-12-25 19:16:00.915 13115-13115/com.bj.gxz.h264decoderdemo D/H264: OMX.google.amrwb.decoder 2020-12-25 19:16:00.915 13115-13115/com.bj.gxz.h264decoderdemo D/H264: OMX.google.flac.decoder 2020-12-25 19:16:00.915 13115-13115/com.bj.gxz.h264decoderdemo D/H264: OMX.google.g711.alaw.decoder 2020-12-25 19:16:00.915 13115-13115/com.bj.gxz.h264decoderdemo D/H264: OMX.google.g711.mlaw.decoder 2020-12-25 19:16:00.915 13115-13115/com.bj.gxz.h264decoderdemo D/H264: OMX.google.gsm.decoder 2020-12-25 19:16:00.915 13115-13115/com.bj.gxz.h264decoderdemo D/H264: OMX.google.mp3.decoder 2020-12-25 19:16:00.915 13115-13115/com.bj.gxz.h264decoderdemo D/H264: OMX.google.opus.decoder 2020-12-25 19:16:00.915 13115-13115/com.bj.gxz.h264decoderdemo D/H264: OMX.google.raw.decoder 2020-12-25 19:16:00.915 13115-13115/com.bj.gxz.h264decoderdemo D/H264: OMX.google.vorbis.decoder 2020-12-25 19:16:00.915 13115-13115/com.bj.gxz.h264decoderdemo D/H264: OMX.hisi.video.decoder.avc 2020-12-25 19:16:00.915 13115-13115/com.bj.gxz.h264decoderdemo D/H264: OMX.google.h264.decoder 2020-12-25 19:16:00.915 13115-13115/com.bj.gxz.h264decoderdemo D/H264: OMX.google.h263.decoder 2020-12-25 19:16:00.915 13115-13115/com.bj.gxz.h264decoderdemo D/H264: OMX.hisi.video.decoder.hevc 2020-12-25 19:16:00.915 13115-13115/com.bj.gxz.h264decoderdemo D/H264: OMX.google.hevc.decoder 2020-12-25 19:16:00.915 13115-13115/com.bj.gxz.h264decoderdemo D/H264: OMX.hisi.video.decoder.mpeg2 2020-12-25 19:16:00.915 13115-13115/com.bj.gxz.h264decoderdemo D/H264: OMX.hisi.video.decoder.mpeg4 2020-12-25 19:16:00.915 13115-13115/com.bj.gxz.h264decoderdemo D/H264: OMX.google.mpeg4.decoder 2020-12-25 19:16:00.915 13115-13115/com.bj.gxz.h264decoderdemo D/H264: OMX.hisi.video.decoder.vp8 2020-12-25 19:16:00.915 13115-13115/com.bj.gxz.h264decoderdemo D/H264: OMX.google.vp8.decoder 2020-12-25 19:16:00.915 13115-13115/com.bj.gxz.h264decoderdemo D/H264: OMX.google.vp9.decoder 2020-12-25 19:16:00.915 13115-13115/com.bj.gxz.h264decoderdemo D/H264: Encoders: 2020-12-25 19:16:00.915 13115-13115/com.bj.gxz.h264decoderdemo D/H264: OMX.google.aac.encoder 2020-12-25 19:16:00.915 13115-13115/com.bj.gxz.h264decoderdemo D/H264: OMX.google.amrnb.encoder 2020-12-25 19:16:00.915 13115-13115/com.bj.gxz.h264decoderdemo D/H264: OMX.google.amrwb.encoder 2020-12-25 19:16:00.915 13115-13115/com.bj.gxz.h264decoderdemo D/H264: OMX.google.flac.encoder 2020-12-25 19:16:00.915 13115-13115/com.bj.gxz.h264decoderdemo D/H264: OMX.hisi.video.encoder.avc 2020-12-25 19:16:00.915 13115-13115/com.bj.gxz.h264decoderdemo D/H264: OMX.google.h264.encoder 2020-12-25 19:16:00.915 13115-13115/com.bj.gxz.h264decoderdemo D/H264: OMX.google.h263.encoder 2020-12-25 19:16:00.915 13115-13115/com.bj.gxz.h264decoderdemo D/H264: OMX.hisi.video.encoder.hevc 2020-12-25 19:16:00.915 13115-13115/com.bj.gxz.h264decoderdemo D/H264: OMX.google.mpeg4.encoder 2020-12-25 19:16:00.915 13115-13115/com.bj.gxz.h264decoderdemo D/H264: OMX.google.vp8.encoder 2020-12-25 19:16:00.915 13115-13115/com.bj.gxz.h264decoderdemo D/H264: OMX.google.vp9.encoder
  看一下命名,软解码器通常都是 OMX.google  以开头的,就像上面那个一样OMX.google.h264.decoder  。硬解码器是基于OMX.[hardware_vendor]  一开始的,像上面那个应该是海思芯片OMX.hisi.video.decoder.avc   。hisi  当然也有一些不遵守这个规则的,系统会认为它是软解码器。编码器的名称是相同的。来自Android系统的源码可以判断规则,
  源码地址:http ://androidos.net.cn/android/6.0.1_r16/xref/frameworks/av/media/libstagefright/OMXCodec.cpp static bool IsSoftwareCodec(const char *componentName) {     if (!strncmp("OMX.google.", componentName, 11)) {         return true;     }      if (!strncmp("OMX.", componentName, 4)) {         return false;     }      return true; } MediaCodec 处理数据的类型
  MediaCodec 非常强大,支持的编解码数据类型有:压缩音频数据、压缩视频数据、原始音频数据和原始视频数据,并且支持不同封装格式的编解码,如前所述,如果是硬解码,当然,也需要手机厂商的支持。您可以通过设置 Surface 来获取/呈现原始视频数据。MediaCodec 关于 API 每个方法和参数都有自己的含义。你可以慢慢深入地使用它。 MediaCodec 的编解码过程
  下图是Android官方文档提供的,官方文档很详细。
  https://developer.android.google.cn/reference/android/media/MediaCodec?hl=en
  MediaCodec 处理输入数据产生输出数据,异步处理数据时,使用一组输入输出ByteBuffer。该过程通常是 将数据填充到预设的输入缓冲区(ByteBuffer)中, 输入缓冲区填满数据后,传递给 MediaCodec 的编码和解码处理。经过编码和解码后,它会在 . 然后用户可以得到编码和解码后的数据,然后将ByteBuffer释放回MediaCodec,往复循环。
  需要注意的是, Buffer 并不是我们自己对 MediaCodec 的新对象,它是 MediaCodec 为了更好地控制 Buffer 来处理,我们需要使用 MediaCodec 提供的方法来获取,然后将数据插入其中并获取数据。 媒体编解码器 APIMediaCodec 的创建createDecoderByType/createEncoderByType:根据具体的MIME类型(如"video/avc")建立codec。Decoder就是decoder,Encoder就是encoder。createByCodecName: 知道组件的确切名称(如 OMX.google.h264.decoder)时,从组件名称编解码器创建。使用 MediaCodecList 可以获取组件的名称,如上所述。 configure:配置解码器或编码器。比如可以配置解码后的数据通过surface来显示,本文下面部分是解码h264的demo配置surface来把yuv的数据渲染到surface上。 start:开始编解码,等待数据。 数据处理,开始编解码dequeueInputBuffer:返回一个有效的输入缓冲区的索引queueInputBuffer: 输入流入队列。通常是用数据填充它dequeueOutputBuffer:从输出队列中取出编码/解码数据,如果输入的数据较多,可能需要循环读取,一般在写代码的时候需要调用循环releaseOutputBuffer: 释放ByteBuffer数据返回给MediaCodecgetInputBuffers: 获取需要对数据进行编码和解码的输入流队列,返回一个 ByteBuffer ArraygetOutputBuffers: 获取编解码后的数据输出流队列,返回一个ByteBuffer数组 flush:清空输入输出队列缓冲区 stop:停止编解码 release: 发布编解码器
  从上面的api我可以看到电影MediaCodec编解码器API的生命周期,可以再看官网。 MediaCodec 的同步和异步编解码器同步方式
  官方样本 MediaCodec codec = MediaCodec.createByCodecName(name);  codec.configure(format, …);  MediaFormat outputFormat = codec.getOutputFormat(); // option B  codec.start();  for (;;) {   int inputBufferId = codec.dequeueInputBuffer(timeoutUs);   if (inputBufferId >= 0) {     ByteBuffer inputBuffer = codec.getInputBuffer(…);     // fill inputBuffer with valid data     …     codec.queueInputBuffer(inputBufferId, …);   }   int outputBufferId = codec.dequeueOutputBuffer(…);   if (outputBufferId >= 0) {     ByteBuffer outputBuffer = codec.getOutputBuffer(outputBufferId);     MediaFormat bufferFormat = codec.getOutputFormat(outputBufferId); // option A     // bufferFormat is identical to outputFormat     // outputBuffer is ready to be processed or rendered.     …     codec.releaseOutputBuffer(outputBufferId, …);   } else if (outputBufferId == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {     // Subsequent data will conform to new format.     // Can ignore if using getOutputFormat(outputBufferId)     outputFormat = codec.getOutputFormat(); // option B   }  }  codec.stop();  codec.release();
  流程如下: -  Create and configure MediaCodec object  -  Loop until it"s done :   -  If input buffer Be on it      -  Read a piece of input , Fill it in with input buffer Encoding and decoding are performed in the system    -  If the output buffer Be on it :     -  From output buffer Get the data after encoding and decoding for processing . -  After processing , The destruction  MediaCodec  object . 异步方式
  在Android 5.0,API21,引入异步模式。官方样品: MediaCodec codec = MediaCodec.createByCodecName(name);  MediaFormat mOutputFormat; // member variable  codec.setCallback(new MediaCodec.Callback() {   @Override   void onInputBufferAvailable(MediaCodec mc, int inputBufferId) {     ByteBuffer inputBuffer = codec.getInputBuffer(inputBufferId);     // fill inputBuffer with valid data     …     codec.queueInputBuffer(inputBufferId, …);   }     @Override   void onOutputBufferAvailable(MediaCodec mc, int outputBufferId, …) {     ByteBuffer outputBuffer = codec.getOutputBuffer(outputBufferId);     MediaFormat bufferFormat = codec.getOutputFormat(outputBufferId); // option A     // bufferFormat is equivalent to mOutputFormat     // outputBuffer is ready to be processed or rendered.     …     codec.releaseOutputBuffer(outputBufferId, …);   }     @Override   void onOutputFormatChanged(MediaCodec mc, MediaFormat format) {     // Subsequent data will conform to new format.     // Can ignore if using getOutputFormat(outputBufferId)     mOutputFormat = format; // option B   }     @Override   void onError(…) {     …   }  });  codec.configure(format, …);  mOutputFormat = codec.getOutputFormat(); // option B  codec.start();  // wait for processing to complete  codec.stop();  codec.release(); -  Create and configure MediaCodec object . -  to MediaCodec Object settings callback MediaCodec.Callback -  stay onInputBufferAvailable Calling back :     -  Read a piece of input , Fill it in with input buffer Encoding and decoding are performed in the system  -  stay onOutputBufferAvailable Calling back :     -  From output buffer After encoding and decoding, the data is processed . -  After processing , The destruction  MediaCodec  object . 解码h264视频
  让我们解码视频中的一个h264(摘自tiktok的一段话。/葵h264文件).h265是一回事,只要了解h264.h265的编码方式和原理以及码流结构,都是小菜一碟。为了更好地理解 h264 的比特流数据,我们演示了一次只读取内存中的文件 byte 数据。
  我们从两个方面来处理,都可以正常播放,只是我们对h264 Stream数据有了更深入的了解。 就是我们做的h264比特流结构,一次一个的NAL单元(NALU)偷偷给MediaCodec,包括第一个SPS,PPS。 是的,我们只是截取几个 k,然后用 MediaCodec 填充它
  首先初始化MediaCodec     var bytes: ByteArray? = null     var mediaCodec: MediaCodec     init {         // demo test , To facilitate one-time access to memory          bytes = FileUtil.getBytes(path)         // video/avc Namely H264, Create decoder          mediaCodec = MediaCodec.createDecoderByType("video/avc")         val mediaFormat = MediaFormat.createVideoFormat("video/avc", width, height)         mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 15)         mediaCodec.configure(mediaFormat, surface, null, 0)     }
  方式一:划分NAL单元(NALU)方式     private fun decodeSplitNalu() {         if (bytes == null) {             return         }         //  Data start subscribing          var startFrameIndex = 0         val totalSizeIndex = bytes!!.size - 1         Log.i(TAG, "totalSize=$totalSizeIndex")         val inputBuffers = mediaCodec.inputBuffers         val info = MediaCodec.BufferInfo()         while (true) {             // 1ms=1000us  subtle              val inIndex = mediaCodec.dequeueInputBuffer(10_000)             if (inIndex >= 0) {                 //  Split a frame of data                  if (totalSizeIndex == 0 || startFrameIndex >= totalSizeIndex) {                     Log.e(TAG, "startIndex >= totalSize-1 ,break")                     break                 }                 val nextFrameStartIndex: Int =                     findNextFrame(bytes!!, startFrameIndex + 1, totalSizeIndex)                 if (nextFrameStartIndex == -1) {                     Log.e(TAG, "nextFrameStartIndex==-1 break")                     break                 }                 //  Fill in the data                  val byteBuffer = inputBuffers[inIndex]                 byteBuffer.clear()                 byteBuffer.put(bytes!!, startFrameIndex, nextFrameStartIndex - startFrameIndex)                  mediaCodec.queueInputBuffer(inIndex, 0, nextFrameStartIndex - startFrameIndex, 0, 0)                  startFrameIndex = nextFrameStartIndex              }             var outIndex = mediaCodec.dequeueOutputBuffer(info, 10_000)                          while (outIndex >= 0) {                 //  Here"s a simple temporal way to keep the video alive fps, Otherwise the video will play very fast                  // demo  Of H264 File is 30fps                 try {                     sleep(33)                 } catch (e: InterruptedException) {                     e.printStackTrace()                 }                 //  Parameters 2  Render to surface On ,surface Namely mediaCodec.configure Parameters of 2                 mediaCodec.releaseOutputBuffer(outIndex, true)                 outIndex = mediaCodec.dequeueOutputBuffer(info, 0)             }         }     }
  NALU分割方法     private fun findNextFrame(bytes: ByteArray, startIndex: Int, totalSizeIndex: Int): Int {         for (i in startIndex..totalSizeIndex) {             // 00 00 00 01 H264 Start code for              if (bytes[i].toInt() == 0x00 && bytes[i + 1].toInt() == 0x00 && bytes[i + 2].toInt() == 0x00 && bytes[i + 3].toInt() == 0x01) { //                Log.e(TAG, "bytes[i+4]=0X${Integer.toHexString(bytes[i + 4].toInt())}") //                Log.e(TAG, "bytes[i+4]=${(bytes[i + 4].toInt().and(0X1F))}")                 return i                 // 00 00 01 H264 Start code for              } else if (bytes[i].toInt() == 0x00 && bytes[i + 1].toInt() == 0x00 && bytes[i + 2].toInt() == 0x01) { //                Log.e(TAG, "bytes[i+3]=0X${Integer.toHexString(bytes[i + 3].toInt())}") //                Log.e(TAG, "bytes[i+3]=${(bytes[i + 3].toInt().and(0X1F))}")                 return i             }         }         return -1     }
  方式一:固定字节数据填充     private fun findNextFrameFix(bytes: ByteArray, startIndex: Int, totalSizeIndex: Int): Int {         //  Every time, it"s better to make the data bigger , Otherwise, it"s like a weak network , Slow data flow leads to video card          val len = startIndex + 40000         return if (len > totalSizeIndex) totalSizeIndex else len     }
  说明:在实际项目中,通常是web/数据流塞进去的方式,只是给大家demo演示MediaCodec解码h264文件播放。 保存 decode h264 视频 yuv 数据为图片
  我们保存在哪里呢,前面说了,解码后一定是h264保存,解码后的数据就是yuv数据。也就是说 dequeueOutputBuffer  然后取出解码后的数据,然后使用YuvImage  Class compressToJpeg  Save as Jpeg Just图片。我们 3s 保持一个。
  本地代码:                // 3s  Save a picture                  if (System.currentTimeMillis() - saveImage > 3000) {                     saveImage = System.currentTimeMillis()                      val byteBuffer: ByteBuffer = mediaCodec.outputBuffers[outIndex]                     byteBuffer.position(info.offset)                     byteBuffer.limit(info.offset + info.size)                     val ba = ByteArray(byteBuffer.remaining())                     byteBuffer.get(ba)                      try {                         val parent =                             File(Environment.getExternalStorageDirectory().absolutePath + "/h264pic/")                         if (!parent.exists()) {                             parent.mkdirs()                             Log.d(TAG, "parent=${parent.absolutePath}")                         }                          //  take NV21 Format picture , With quality 70 Compressed into Jpeg                         val path = "${parent.absolutePath}/${System.currentTimeMillis()}-frame.jpg"                         Log.e(TAG, "path:$path")                         val fos = FileOutputStream(File(path))                         val yuvImage = YuvImage(ba, ImageFormat.NV21, width, height, null)                         yuvImage.compressToJpeg(                             Rect(0, 0, yuvImage.getWidth(), yuvImage.getHeight()),                             80, fos)                         fos.flush()                         fos.close()                     } catch (e: IOException) {                         e.printStackTrace()                     }                 }
  最后,硬解码速度很快,效率很高,播放视频需要PTS时间戳处理.demo最好的办法就是让它渲染慢一点(demo视频文件是30fps,也就是说1000ms/30= 33ms一帧yuv数据),所以在 mediaCodec.releaseOutputBuffer(outIndex, true)  休眠前(33ms)达到正常播放速度。

生活中的这些黄金时间,你知道吗?每个人都希望能在对的时间做对的事健康生活这方面也是一样你知道吗?不论是喝水洗澡还是排便其实都有自己的黄金时间让你受益更多喝水的两个黄金时间水是生命之源,当水分丢失量为体重的1时,人漫游西南200天(day68)2021年12月8日,景洪,晴一觉睡到日上三竿,连日奔波的疲惫已经烟消云散。与先生一起出门去熟悉一下周围的环境,出了曼贡村的北门才发现,马路的对面就是西双版纳自治州民族医药研究所傣这条高速湖北段全线贯通日前由湖北交投集团投资建设的十堰至淅川高速公路(湖北段)通过交工验收十淅高速公路(湖北段)起于丹江口市石鼓镇,与西峡至十堰高速公路河南段对接,止于丹江口市丁家营镇,与福银高速公路衔哥与姐(小说)二hr早上起来才九点,没事可做,去广场看看,别看我们这里档次不咋地,可是离最大的广场也就两公里。顺着门前马路步行,一公里后拐弯,再有一公里,就是燕京最大的广场。这里永远不缺人,拍照亲子六则五知识的力量(上)文佑我浮生马克思曾经这样说过任何时候,我也不会满足,越是多读书,就越是深刻地感到不满足,越感到自己知识贫乏。科学是奥妙无穷的。奇奇很喜欢看书,从很小的时候起就对文字有很高的求知欲,太遗憾!国乒男单名将正式宣布退役,刚参加完乒超联赛,只有22岁北京时间12月12日,国乒乒超联赛已经顺利落幕。与此同时,国乒男队方面传来最新消息,男单名将于何一正式宣布退役。于何一在乒超联赛中加盟深圳宝安俱乐部,在没有主力加盟的情况下,于何一等了30年!Windows95展示的功能在Windows11上正式落地早在Windows10时代的技术预览版中就曾出现资源管理器的多标签功能。简单来说与现如今浏览器多标签工作方式如出一辙,允许用户在一个窗口以标签的形式打开多层级多目录。不过,由于不稳空气消毒机为什么比空气净化器更贵?贵在哪空气消毒空气净化的产品非常多,目前市面上比较主流的当属空气消毒机和空气净化器,因为疫情原因,导致以往多用于医用领域的空气消毒机被越来越多的人关注到,只是很多人看到空气消毒机的价格会为了攒钱,就得委屈自己哈喽,大家好,我是沐子最近,在付费的社群里,听到最多的一个词就是攒钱!有人说为了攒钱养家,这一年连一件像样的衣服都没有买过。还有人说这三年口罩的原因,才知道攒钱才是成年人最好在生存我是初中生,嫁给了人民教师,婚后尽是苦楚原创不易,抄袭必究,如若转载,请注明出处。人这一生,未知的事情无人知晓,更没有谁知道,谁会是谁的过客,谁会是谁的终点。当爱情来了,心被触动了,便扑面而来,接着迎接它的灵魂,感受它的2022年末,大总结(太精辟了!)来源于云谷师慈怀读书会202212120630发表于上海兹心说不觉年末将至,只愿尘世冬安。佛曰三千繁华,弹指刹那。岁月流转,时光匆匆。转眼,2022年就进入了倒计时。回首这一年,谁
本周外汇基本面分析本周重点关注周二加拿大CPI及澳联储货币政策会议纪要周四0200美联储利率决议0230美联储主席鲍威尔新闻发布会1100日本央行利率决议1530瑞士央行利率决议1900英国央行利率国际金价持续下跌!美元越强势金价就越低,现在是入手的好时机吗列位欢迎来到照理说事。这两年以来,大家有没有发觉我们这个投资渠道越来越狭窄,而且利率是越来越低。是的,我们正在步入一个低利率时代,你想,就从住房贷款这个事上就能看得出来,现在很多城超级央行周来袭!10余家央行将公布利率决议每经记者文巧每经编辑兰素英上周二公布的美国8月CPI数据引发了美股市场的剧烈震荡,由于通胀数据仍处于高位,市场对美联储强势加息的预期急剧上升。本周,除了全球市场关注的焦点美联储将公美国巨头被赶出中国,垄断市场长达30年,曾说绝不培养中国员工虽然我国目前是世界第二大经济体,但是我国整体的发展起步较晚,在过去很长一段时间内,西方国家凭借技术优势,在我国抢占市场并形成了垄断。就有这么一家美国企业,垄断市场长达30年,其创始走进县城看发展丨内蒙古五原产业融合走出发展新路央视网消息(新闻联播)金秋时节,内蒙古五原县一派丰收景象。金灿灿的黄柿子,粒粒饱满的葵花,品类繁多的特色瓜果,长满田地挂满枝头。内蒙古巴彦淖尔市五原县黄柿子种植户郝新乐亩产达到1万吸纳利用数字化人才,传统产业亟需转型!新版职业教育专业简介发布意味着什么2022年9月,教育部发布新版职业教育专业简介。作为职业教育介绍专业基本信息与人才培养核心要素的标准文本职业教育国家教学标准体系的重要组成部分,新版简介全面贯彻新发展理念,服务产业工信部提升动力电池回收利用水平支持相关产业发展来源人民网原创稿人民网北京9月19日电(王绍绍)近日,工信部对外公开对十三届全国人大五次会议第3775号建议答复(工信建议2022230号以下简称答复),针对胡成中等3位全国人大代休闲度假旅游高质量发展满足多元化消费增长需求8月24日,中共中央宣传部举行中国这十年系列主题新闻发布会,介绍推动新时代文化和旅游高质量发展有关情况。发布会上,文化和旅游部有关负责人表示,休闲度假旅游是十年来旅游业发展的三大亮龙口文化赋能手造高质量发展五彩缤纷,百花齐放,琳琅满目,这些天的山东国际会展中心,来自国内和山东16地市的中华手造山东手造产品,将第三届中国文旅博览会首届中华传统工艺大会装扮得熠熠生辉,更将好客尽显真情,好中国前8月吸引外资增长超过20,将重点加大制造业引资力度记者王玉今年18月,中国吸引外资同比增长超过20。国家发改委周一表示,正抓紧推动出台鼓励外商投资产业目录(2022年版),以制造业为重点,进一步加大引资力度。商务部周一发布的数据显建设制造强国,把制造业做实做优做强来源人民网人民日报从2012年到2021年,工业增加值从20。9万亿元增长到37。3万亿元,年均增长6。3制造业增加值从16。98万亿元增加到31。4万亿元,占全球比重从20左右提原创游记忆海南我今年已是古稀之年。无所事事时,就常常回首过往。自己记忆中的最爱是三去海南。(一)1990年10月末,单位有个到广东湛江出差的机会。相比现在,从前的交通不方便,要从家到沈阳,沈阳飞游沙湾,吃不完的美食,逛不完的美景!九分山丘一分坝,一条大河绕城过。沙湾地处四川盆地西南边缘,因灵山秀水,沙岸湾环而得名,是乐山名山名佛名人名城的重要组成部分。尝不完的美食,看不完的美景如今的沙湾能满足所有人的期待与路线已备好,出发!美食线路游古城赏美景吃美食逛吃地图吃是一种享受去哪吃?吃点儿啥?也是一门学问为了给你们推荐好吃的小编搜罗了两条美食线路你可以选择周末的一天从街头吃到巷尾无论是清晨傍晚饭点或是宵夜这为了名垂千古,慈禧在清东陵都干了什么?头条带你乐享河北河北文旅看图识景这么近那么美周末到河北1908年11月15日。慈禧太后因病死于西苑的仪鸾殿,终年74岁。慈禧照片。图源wiki慈禧的侄女,同时也是清朝的新掌门人隆裕中老年男人的眉毛变长,意味着什么?说明长寿吗?原因要心里有数你发现了吗,在仙侠剧里,老仙人的眉毛总是很长,给人一种仙气十足的感觉。现实生活中,许多老人也留有长长的眉毛,于是乎,长眉成为了长寿福气的象征。那么,这些说法到底是真是假?今天九叔就泥沙型胆结石,多吃这两类食物最快两个月排出对于泥沙型胆结石的发病,中医的观点是由于饮食不节,或暴饮暴食,损伤脾胃脾失健运,水湿不化,积湿成痰,痰混内生,阻碍气机,气机郁滞胆汁疏泄失常,郁久化热化火,痰湿生热,湿热与痰互结,女性养生,这四种食物有所助益,赶快来看看在现代生活中,妇科疾病已经成为了危害女性人体健康的重要因素之一。越来越多的女人被妇科疾病所困扰。对此,我们更应该防患于未然。而除了药物治疗外,通过一些食物药膳治疗这些病症便是我们的羊肉是心脑血管疾病的罪魁祸首?想要血管通畅,少吃这类食物众所周知,心脑血管疾病是由心脑血管堵塞,或是心脑血管破裂后引发血栓而引起的一种常见疾病,就目前临床数据显示,这种疾病的发病率不仅一直居高不下,而且还伴随有年轻化和逐年上升的趋势,尤露营风带火大号充电宝,便携式储能市场钱景如何?华夏时报(www。chinatimes。net。cn)记者葛爱峰见习记者胡梦然深圳报道中秋露营游房车游在今年尤其火热。据携程数据,中秋节假期露营相关订单GMV相比端午节增长近六成,黄金崩了!金价创2年来新低美国市场重演股债双杀,道指收跌173点隔夜美国市场再次上演股债双杀,对利率敏感的2年期美债收益率继续刷新近十五年以来的高位,长短期美债息差扩大,2年和30年期美债收益率以及5年期和10年期美债收益率的倒挂程度均为本世纪早安动态图片心语,顺颂金秋安康,快乐幸福美满早安动态图片心语,顺颂金秋安康,快乐幸福美满。金风银霜菊芬芳,红枫黄杏飘秋妆,最是一年景好处,枝头挂满瓜果香。一天之计在于晨,今天有个好心情。拥抱晨曦,拥抱清风,放飞心情,坚定信念